setting.py 配置文件
在 Django 的 settings.py
文件中,LANGUAGE_CODE
和 TIME_ZONE
是重要的配置选项,它们分别用于设置语言代码和时区。这两个设置可以根据您的需求进行自定义,但有一些规范和建议需要遵循。
LANGUAGE_CODE
LANGUAGE_CODE
用于指定您应用的默认语言。默认为:
LANGUAGE_CODE = 'en-us' # 英文(美国)
- 可用值:
- 该值应该是有效的语言代码,通常使用 ISO 639-1 标准(两个字母的语言代码)和国家/地区的 ISO 3166-1 标准(两个字母的国家代码),以连字符(
-
)连接。 - 常见值:
- 英文(美国):
'en-us'
- 中文(简体):
'zh-hans'
- 中文(繁体):
'zh-hant'
- 西班牙语:
'es'
- 法语:
'fr'
- 英文(美国):
- 该值应该是有效的语言代码,通常使用 ISO 639-1 标准(两个字母的语言代码)和国家/地区的 ISO 3166-1 标准(两个字母的国家代码),以连字符(
TIME_ZONE
定义:TIME_ZONE
用于设置系统的时区。默认为:
TIME_ZONE = 'UTC' # 设置为协调世界时
- 可用值:
TIME_ZONE
应该是 Django 支持的有效时区,通常可以从 IANA 时区数据库 中查找。- 常见值:
- 协调世界时:
'UTC'
- 北京时间:
'Asia/Shanghai'
- 纽约时间:
'America/New_York'
- 伦敦时间:
'Europe/London'
- 协调世界时:
静态文件添加
在 Django 项目中,静态文件(如 CSS、JavaScript 和图像文件)的管理和组织是至关重要的。合理地配置静态文件目录可以确保项目的可维护性和性能。以下是关于 Django 项目中静态文件的组织、获取逻辑以及与其他框架的不同之处的详细解释。
项目级别的静态目录结构
将静态文件放在项目的根目录下,通常有一个专门的 static
目录。
mysite/
├── static/
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── script.js
│ └── images/
│ └── my_image.jpg
├── manage.py
└── mysite/
└── settings.py
多个 Django 应用,可以在每个应用中创建一个 static
目录,通常结构如下:
blog/
│
├── static/
│ └── blog/
│ ├── css/
│ │ └── blog.css
│ ├── js/
│ │ └── blog.js
│ └── images/
│ └── blog_logo.png
│
├── templates/
│ └── blog/
│ └── index.html
├── models.py
├── views.py
└── ...
在 settings.py
中,添加以下配置,告诉 Django 如何处理静态文件:
import os
# BASE_DIR 表示项目根目录
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 静态文件的 URL (即在浏览器中访问时的前缀)
STATIC_URL = '/static/'
# 指定静态文件的文件夹
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'), # 项目级别的静态文件目录
]
# 你可以使用这个选项来定义不在 STATICFILES_DIRS 里的应用的静态文件的位置,通常不需要手动设置
使用静态文件
首先在模板文件顶部加载静态文件的模板标签库:
{% load static %}
然后可以使用 {% static %}
标签引用静态文件。例如,引用 CSS 和 JavaScript 文件:
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
<script type="text/javascript" src="{% static 'js/script.js' %}"></script>
基于项目https://www.ljh.cool/wp-admin/post.php?post=43305&action=edit
继续完善静态文件内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog Index</title>
<!-- 加载静态文件 -->
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}"> <!-- 引用 CSS 文件 -->
<script type="text/javascript" src="{% static 'js/script.js' %}"></script> <!-- 引用 JS 文件 -->
</head>
<body>
<h1>Welcome to the Blog Index!</h1>
<p>This is where you can find the latest posts.</p>
<!-- 添加静态图片 -->
<h2>My Image:</h2>
<img src="{% static 'images/my_image.jpg' %}" alt="My Image" style="max-width: 100%; height: auto;">
<h2>Posts:</h2>
<ul>
{% for post in posts %}
<li>
<strong>{{ post.title }}</strong><br>
{{ post.content }}<br>
<em>Published on: {{ post.created_at }}</em>
</li>
{% empty %}
<li>No posts available.</li>
{% endfor %}
</ul>
</body>
</html>
打开浏览器,访问静态资源,如 http://127.0.0.1:8000/static/images/my_image.jpg

通过访问 http://127.0.0.1:8000/blog/ 加载静态资源

apps.py 配置
在 Django 中,每个应用(app)都有一个 apps.py
文件,里面定义了一个应用的配置类。默认情况下,当您创建一个新应用时,Django 会自动为您生成这个文件。
在 apps.py
中,您将定义一个继承自 django.apps.AppConfig
的类。这个类主要包含以下内容:
- 名称 (
name
):指定应用的名称,通常是该应用的模块名。 - 标签 (
label
):用于唯一标识该应用的标签,可以是与名不同(可选)。 - 初始化 (
ready
):这是用于初始化日志、信号等的地方。
使用 AppConfig
信号(Signals):Django 信号框架用来处理在特定事件发生时自动执行的逻辑。例如,您可以在创建模型实例时发送通知或记录日志。
应用信号:如果您使用了 Django 的信号机制(例如 post_save
或 pre_save
),通常会在 ready
方法中进行连接。示例如下:
from django.apps import AppConfig
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Post
class BlogConfig(AppConfig):
name = 'blog'
verbose_name = "Blog Application"
def ready(self):
# 在这里连接信号
from . import signals
信号的工作原理
- 信号 是 Django 的一种机制,允许应用程序在某些事件发生时执行特定的操作。例如,当新的
Post
模型实例被保存时,您可能希望自动执行某些操作(如更新其他模型、发送通知等)。 post_save
信号 是在模型实例保存后自动发送的信号。您可以定义一个接收器(receiver)函数来响应这个信号:
@receiver(post_save, sender=Post)
def post_save_handler(sender, instance, created, **kwargs):
if created:
print(f"New post created: {instance.title}")
else:
print(f"Post updated: {instance.title}")
以下是一个示例 apps.py
文件的结构,以 blog
应用为例:
from django.apps import AppConfig
class BlogConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'blog'
verbose_name = "Blog Application" # 应用的可读名称
default_auto_field = 'django.db.models.BigAutoField'
- 从 Django 3.2 开始,引入了
default_auto_field
选项来指定生成模型主键的默认类型。BigAutoField
是一个 64 位整数,可以自动递增,适用于希望支持更大数量记录的应用。 - 使用
BigAutoField
比较适合大型应用,因为它允许比默认的AutoField
(32 位整数)支持更多的记录。
这个配置类有什么用?
- 全局配置:
AppConfig
可以用于管理 Django 应用的元数据,配置如自动字段、显示名称等。 - 信号连接:在将来使用信号(如保存、删除模型时)时,您可以在类的
ready
方法中设置信号的连接。 - 更容易的管理和扩展:通过使用应用程序配置,您能够灵活地管理应用程序的行为。例如,您可以根据环境变量来设置特定于环境的行为。
model.py 模型概述
Django 模型是用于定义数据结构的 Python 类,通常继承自 django.db.models.Model
。模型允许开发者通过 Python 代码描述数据库中的表和字段,Django 的 ORM(对象关系映射)自动将模型转换为数据库表。
为什么使用模型?
- 数据抽象:通过模型,您无需直接编写 SQL 语句,Django 会处理与数据库的交互。
- 数据验证:模型字段提供数据类型和约束,Django 在处理数据前进行验证。
- 易于维护:模型使代码更清晰,便于集中管理与数据相关的逻辑。
Django 模型组成部分
1、类定义:
模型定义为一个 Python 类,例如:
from django.db import models
class Post(models.Model):
...
2、字段定义:
模型属性定义为字段,设置数据类型和约束。常用字段类型包括:
- CharField:用于存储短文本。需要设置最大长度。
- TextField:用于存储长文本,没有长度限制。
- IntegerField:用于存储整数。
- FloatField:用于存储浮点数。
- DecimalField:用于存储固定精度的十进制数,适合金融计算。
- DateField:用于存储日期。
- DateTimeField:用于存储日期和时间。
- BooleanField:用于布尔值(True 或 False)。
- EmailField:用于存储电子邮件地址,自动验证格式。
- URLField:用于存储 URL 地址。
- ImageField/FileField:用于处理文件上传。
3、方法定义:
可以定义方法增加业务逻辑,例如重载 __str__
方法,使其返回可读字符串表示。
def __str__(self):
return self.title
Django 模型字段选项
null
:指示数据库是否可以存储 NULL
值。
title = models.CharField(max_length=200, null=True)
blank
:控制该字段在表单中是否可留空。
title = models.CharField(max_length=200, blank=True)
unique
:指示字段在整个表中必须保持唯一性。
email = models.EmailField(unique=True)
default
:设置字段的默认值。
status = models.CharField(max_length=20, default='draft')
完整的模型示例
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200, null=False, blank=False, unique=True)
content = models.TextField(null=True, blank=True)
author_email = models.EmailField(unique=True)
price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00)
created_at = models.DateTimeField(auto_now_add=True)
is_published = models.BooleanField(default=False)
def __str__(self):
return self.title
在修改模型后,需要运行以下命令生成并应用迁移,以更新数据库结构:
python manage.py makemigrations # 生成迁移文件
python manage.py migrate # 更新数据库
利用 Django ORM 进行操作
使用 Django ORM,通过创建、查询、更新和删除记录进行数据操作:
# 创建记录
new_post = Post(title="My First Post", content="This is the body of my post.")
new_post.save() # 保存到数据库
# 查询记录
all_posts = Post.objects.all() # 获取所有文章
specific_post = Post.objects.get(id=1) # 获取特定文章
# 更新记录
post_to_update = Post.objects.get(id=1)
post_to_update.title = "Updated Title"
post_to_update.save() # 保存更改
# 删除记录
post_to_delete = Post.objects.get(id=1)
post_to_delete.delete() # 删除该文章
模型外键定义
在 Django 中,您可以使用 ForeignKey
字段在模型中建立外键关系。下面是如何实现的详细示例。
假设我们要创建一个博客应用,其中的 Post
模型可以有许多评论(Comment
),而每个评论是对应某个帖子的。您可以在 Comment
模型中定义一个外键来指向 Post
模型。
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200, null=False, blank=False, unique=True)
content = models.TextField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE) # 外键字段,用于链接到 Post
content = models.TextField(null=False, blank=False) # 评论内容
created_at = models.DateTimeField(auto_now_add=True) # 评论创建时间
def __str__(self):
return f'Comment on {self.post.title}' # 显示评论相关的帖子标题
重要参数说明
在 ForeignKey
中,您可以设置一些重要的参数:
on_delete
:指示当关联的对象被删除时,外键字段的行为。
models.CASCADE
:级联删除,如果关联的帖子被删除,则相关的评论也会被删除。models.SET_NULL
:设置为NULL
,前提是外键字段允许NULL
。models.PROTECT
:防止删除关联对象,如果尝试删除将抛出错误。models.SET_DEFAULT
:将外键设置为字段的默认值。
related_name
:用于指定反向关系的名称。在 Comment
模型中可以定义反向关系。例如:
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
这样可以通过 post_instance.comments.all()
获取与该 post_instance
相关的所有评论。
Django ORM 和外键的使用
有了外键字段后,您可以用 Django 的 ORM 轻松查询和管理这两个模型之间的关系。
创建记录
# 创建一个 Post
new_post = Post(title="My First Post", content="This is the content of my first post.")
new_post.save()
# 创建与 Post 关联的 Comment
comment1 = Comment(post=new_post, content="Great post!")
comment1.save()
查询记录
你可以从 Post
模型中获取所有相关的评论:
post = Post.objects.get(id=1) # 获取 ID 为 1 的帖子
comments = post.comments.all() # 获取与该帖子关联的所有评论
for comment in comments:
print(comment.content)
修改表名
以下是如何在 Django 中修改表名的示例:
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200, null=False, blank=False, unique=True)
content = models.TextField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'custom_post_table' # 指定自定义表名
在这个例子中,db_table
属性被设置为了 'custom_post_table'
,这意味着即使 Django 的默认行为下表名为 blog_post
(即应用名称加下划线和模型名称),实际在数据库中将会创建一个名为 custom_post_table
的表。
注意事项:如果已经迁移过数据库并且希望修改表名,您需要执行以下步骤:
- 修改模型的
Meta
类以包含db_table
。(添加class Meta: db_table ='xxx') - 执行
makemigrations
命令生成迁移文件。(python manage.py makemigrations) - 执行
migrate
命令更新数据库。(python manage.py migrate
)
枚举类型
枚举(enum)是一种特殊的类型,可以让你定义一组固定和有限的选项。比如,你可以用它来表示文章的状态,比如 "草稿"(draft)、"已发布"(published)和 "归档"(archived)。使用枚举可以让你的代码更清晰,避免使用字符串。
为什么使用枚举?
- 限制选项:它只允许你选择特定的值。比如,对于文章的状态,你只能选择 "草稿"、"已发布" 或 "归档"。
- 易于维护:如果你想改变或添加状态,只需要在一处修改,不需要到处找。
在 Django 中,你可以通过模型的 choices
属性来使用枚举。这里有一个简单的例子:
from django.db import models
class Post(models.Model): # 定义一个 Post 类(文章)
# 定义文章状态的三个选项
class Status(models.TextChoices):
DRAFT = 'draft', '草稿'
PUBLISHED = 'published', '已发布'
ARCHIVED = 'archived', '归档'
# 定义标题字段
title = models.CharField(max_length=200, unique=True) # 限制最多200个字符,且名称必须唯一
# 定义内容字段
content = models.TextField() # 可以存储任意长的文本
# 定义状态字段,用于选取枚举值
status = models.CharField(max_length=10,
choices=Status.choices, # 允许的选项
default=Status.DRAFT) # 默认状态是草稿
# 创建时间,自动设置为当前时间
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title # 显示文章的标题
- 状态定义:我们创建了一个内部类
Status
,通过TextChoices
定义了三个状态:DRAFT
值为'draft'
,中文显示为'草稿'
PUBLISHED
值为'published'
,中文显示为'已发布'
ARCHIVED
值为'archived'
,中文显示为'归档'
- 标题和内容:
title
字段是用来存文章的标题,而content
字段是用来存文章的内容。 - 状态字段:
status
字段定义了可以选择的状态,它只能是'draft'
、'published'
或'archived'
中的一个。- 如果没有手动设置状态,默认值是
'draft'
。
修改数据库引擎
我这里在 macOS 上操作,对于 Ubuntu 或 windows 用户自行搜索文档:
步骤 1: 安装 MySQL:
brew install mysql
步骤 2: 安装 mysqlclient
库
安装相关的开发工具:
您可能需要安装 pkg-config
及一些开发库。
brew install pkg-config
brew install openssl
brew install mariadb-connector-c
设置环境变量(在虚拟环境中配置)
export PATH="/usr/local/opt/openssl/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/openssl/lib"
export CPPFLAGS="-I/usr/local/opt/openssl/include"
安装 mysqlclient
:
pip install mysqlclient

步骤 3: 修改 settings.py
配置
打开 Django 项目中的 settings.py
文件,找到 DATABASES
部分。您需要将其更改为 MySQL 数据库的配置。以下是一个使用 MySQL 的示例配置:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 设置为 MySQL
'NAME': 'your_database_name', # 您的数据库名称
'USER': 'your_username', # 您的用户名
'PASSWORD': 'your_password', # 您的密码
'HOST': 'localhost', # 数据库主机
'PORT': '3306', # MySQL 的默认端口
}
}
步骤 4: 创建数据库
创建您在 settings.py
中指定的数据库:
CREATE DATABASE your_database_name CHARACTER SET UTF8mb4 COLLATE utf8mb4_unicode_ci;
步骤 5: 迁移数据
在修改数据库引擎并创建数据库后,您需要运行以下命令来生成迁移文件并应用迁移,以在新的 MySQL 数据库上创建所有表:
python manage.py makemigrations
python manage.py migrate
步骤 6: 测试连接
python manage.py runserver
,然后在浏览器中访问 http://127.0.0.1:8000/
,查看应用是否正常工作。
例如:我们将https://www.ljh.cool/43305.html的数据库从 sqlite3 迁移到 mysql 过程:
# 创建数据库:
CREATE DATABASE blog_db CHARACTER SET UTF8mb4 COLLATE utf8mb4_unicode_ci;
# 修改 settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 设置为 MySQL
'NAME': 'blog_db', # 您的数据库名称
'USER': 'root', # 您的用户名
'PASSWORD': 'XXXXXXXX', # 您的密码
'HOST': 'localhost', # 数据库主机
'PORT': '3306', # MySQL 的默认端口
}
}
# 迁移数据
python manage.py makemigrations
python manage.py migrate
查看迁移结果:

后台登录插入一些内容,查看数据库是否成功插入


额外补充:假如使用pymysql
如果您使用 mysqlclient
并且成功地连接了 MySQL 数据库,那么您无需进行额外的配置。默认情况下,Django 会自动识别 mysqlclient
。但是,如果您决定使用 pymysql
作为 MySQL 的数据库驱动程序,您需要在 Django 项目的 __init__.py
文件中添加以下代码:
在 mysite/__init__.py
中添加:
import pymysql
pymysql.install_as_MySQLdb()
这段代码的作用是让 pymysql
作为 MySQLdb
库来使用,因为 Django 的 MySQL 数据库后端默认是 MySQLdb
。这就可以确保 Django 可以使用 pymysql
来与 MySQL 数据库进行交互。如果不在工程包中导入pymysql,会在执行迁移时报错:No module named 'MySQLdb'
Python 的 shell 调试 Django 应用程序
使用 Python 的 shell(REPL 环境)来调试 Django 应用程序可以帮助您理解 ORM(对象关系映射)如何工作,以及如何与数据库交互。您可以在 Django 的 shell 中执行操作,查询数据库等。
使用 Django Shell
在 Django 项目的根目录下(与 manage.py
位于同一目录)打开命令行或终端,然后输入以下命令进入 Django shell:
python manage.py shell
这将启动一个 Python 交互式 shell,您可以在其中直接使用 Django 的模型和功能。
一些基本操作
导入模型:
首先,您需要导入 Post
模型:
from blog.models import Post
这里的 blog
是您的 Django 应用名称,如果您的应用名称不同,请相应地更改。
创建新文章:
例如,您可以使用以下代码创建一个新的 Post
实例:
实例方法创建
new_post = Post(title="My First Post", content="This is the content of my first post.")
new_post.save() # 保存到数据库
查询集方法创建
在需要更多灵活性和控制的情况下,使用 .save()
方法会更合适。如果您仅仅是创建新对象并保存,无需复杂逻辑,Post.objects.create()
可能是更为优雅和简洁的选择。
Post.objects.create(title="My Second Post", content="This is the content of my second post.")
批量创建
使用 bulk_create()
方法可以一次性创建多个对象。例如,假设我们要创建多个新的 Post
对象,可以这样做:
from yourapp.models import Post # 替换为你的实际应用和模型导入
# 创建多个 Post 对象
posts_to_create = [
Post(title="博客文章 1", content="内容 1", status="已发布"),
Post(title="博客文章 2", content="内容 2", status="草稿"),
Post(title="博客文章 3", content="内容 3", status="已发布"),
]
# 批量创建
Post.objects.bulk_create(posts_to_create)
- 实例方法适合于你需要获取具体的对象实例时,便于后续对该实例的其他操作。
- 查询集方法适合于批量操作,且更为高效和简洁,特别是在处理大量数据时。
更新文章:
您可以更新某个文章的标题或内容:
实例方法更新
post = Post.objects.get(id=1) # 获取 ID 为 1 的 Post
post.title = "修改标题后的博客文章 1" # 更新标题
post.save() # 保存更改
查询集方法更新
当你要更新多条记录时,可以使用 update()
方法借助 filter()
来实现 。filter()
返回的结果是多个对象的列表
Post.objects.filter(id=1).update(title="修改标题后的博客文章 1")
删除文章:
使用 get()
方法获取对象并调用 delete()
方法来删除数据
post_to_delete = Post.objects.get(id=1) # 获取要删除的 Post
post_to_delete.delete() # 删除该 Post
使用 filter()
方法结合 delete()
方法来删除数据
Post.objects.filter(id=1).delete()
Django Shell 查询操作(重点)
目前数据库内容:

1. 查询所有文章:
获取所有的帖子并输出它们:
posts = Post.objects.all() # 获取所有 Post 数据,返回结果为列表
for post in posts:
print(post.title) # 打印每个 Post 的标题
2. 获取特定文章:
如果您知道某个帖子的 ID,可以轻松获取该帖子的内容:
post = Post.objects.get(id=1) # 根据 ID 获取 Post,使用 get() 返回结果为单个对象
print(post.content) # 打印该 Post 的内容
3. 使用特定字段查询:
如果不知道帖子的 ID,可以通过其他属性进行查询。例如,通过标题或作者:
例如通过标题查询(如果查询的结果不存在,建议进行异常捕获)
# 假设要查找标题为 "博客文章 1" 的 Post
try:
post = Post.objects.get(title="博客文章 1") # 根据标题获取 Post
print(post.content) # 打印该 Post 的内容
except Post.DoesNotExist:
print("没有找到该标题的帖子")
4. 使用 filter()
方法
filter()
方法可以用来根据某些条件获取多个对象。可以链式使用多个过滤条件:
# 获取状态为 "已发布" 的所有文章
published_posts = Post.objects.filter(status='已发布')
for post in published_posts:
print(post.title)
你还可以使用 Q
对象组合查询条件,支持 OR 查询:
假设你想查找标题包含 "博客" 或者内容中包含 "first" 的文章。可以使用 Q
对象:
from django.db.models import Q
# 查询标题包含 "博客" 或内容中包含 "first" 的帖子
posts = Post.objects.filter(Q(title__icontains='博客') | Q(content__icontains='first'))
for post in posts:
print(f'Title: {post.title}, Content: {post.content}')
5. 排序和限制结果
你可以使用 order_by()
方法对查询结果进行排序,使用 first()
或 last()
获取第一条或最后一条记录。
# 获取按发布日期降序排列的所有文章
# 按创建时间降序获取所有文章
posts = Post.objects.order_by('-created_at')
for post in posts:
print(f'Title: {post.title}, Created At: {post.created_at}')
# 获取创建时间最新的文章
latest_post = Post.objects.order_by('-created_at').first()
if latest_post:
print(f'最新文章: Title: {latest_post.title}, Created At: {latest_post.created_at}')
6. 使用切片
你可以使用切片来限制返回的结果数,例如获取前十条记录:
# 获取前两篇文章
top_two_posts = Post.objects.all()[:2]
for post in top_two_posts:
print(f'Title: {post.title}, Created At: {post.created_at}')
7. 计数
你可以使用 count()
方法获取符合某个条件的记录数:
# 获取文章总数
total_posts = Post.objects.count()
print(f'总文章数: {total_posts}')
Django ORM 中一些复杂的查询语法技巧
我们要创建两个新的表:Author
表和 Comment
表
在 models.py
文件中定义两个新表对象:
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
bio = models.TextField(blank=True, null=True)
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='posts')
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(Author, on_delete=models.CASCADE)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'Comment by {self.author.name} on {self.post.title}'
创建迁移文件并应用
# 创建迁移文件
python manage.py makemigrations
# 应用迁移到数据库
python manage.py migrate
测试数据的插入
python manage.py shell
在 shell 中执行:
from blog.models import Author, Post, Comment # blog 修改为你的应用名
# 创建作者
author1 = Author.objects.create(name="用户A", bio="技术爱好者")
author2 = Author.objects.create(name="用户B", bio="博客写手")
# 创建帖子
post1 = Post.objects.create(title="Django 入门", content="这是关于Django的基本知识.", author=author1)
post2 = Post.objects.create(title="Python 进阶", content="深入理解Python的特性.", author=author2)
# 创建评论
Comment.objects.create(post=post1, author=author2, content="非常棒的文章!")
Comment.objects.create(post=post1, author=author1, content="谢谢!")
Comment.objects.create(post=post2, author=author2, content="图文并茂,学习到了很多!")
插入结果:

数据操作
1. F 对象
用途:F
对象允许你在查询中引用模型字段的值,以便进行比较、算术运算等。这在需要根据同一模型的不同字段进行操作时非常有用。
示例:
假设你有一个 Post
模型,包含 likes
字段。你想找到所有点赞数大于 10 的帖子,并增加它们的点赞数。
from django.db.models import F
# 增加点赞数
Post.objects.filter(likes__gt=10).update(likes=F('likes') + 1) # 增加点赞数
2. Q 对象
用途:Q
对象用于构建复杂查询,支持逻辑运算符(如 AND、OR)。它使得组合多个查询条件变得更加灵活。
示例:
查找所有由“用户A”创作的帖子,或者评论内容中包含“图文并茂”的帖子:
from django.db.models import Q
posts = Post.objects.filter(Q(author__name='用户A') | Q(comments__content__icontains='图文并茂')).distinct()
for post in posts:
print(f'Title: {post.title}, Author: {post.author.name}')
3. 聚合函数
用途:
Django 提供了一些内置的聚合函数(如 Sum
、Count
、Avg
、Max
和 Min
),用于在查询中获取统计信息。
示例:
获取每个作者所创作的帖子数量:
from django.db.models import Count
authors_with_post_count = Author.objects.annotate(post_count=Count('posts'))
for author in authors_with_post_count:
print(f'Author: {author.name}, Post Count: {author.post_count}')
4. 关联查询
用途:
通过外键关系在查询中涉及多个表。Django ORM 允许通过模型属性轻松进行多表查询。
示例:
获取所有评论以及对应的帖子标题和作者:
comments = Comment.objects.select_related('post', 'author') # 使用 select_related 来优化查询
for comment in comments:
print(f'Comment by {comment.author.name} on post "{comment.post.title}": {comment.content}')
5. 使用 annotate()
进行复杂查询
用途:annotate()
方法用于在查询集上添加计算字段,以汇总数据或计算汇总值。
示例:
获取每个帖子的评论数量:
from django.db.models import Count
posts_with_comment_count = Post.objects.annotate(comment_count=Count('comments'))
for post in posts_with_comment_count:
print(f'Post: {post.title}, Comment Count: {post.comment_count}')
6. 复杂的筛选条件使用 exclude()
用途:exclude()
方法用于从查询结果中排除满足特定条件的记录。
示例:
获取所有不是由“用户A”创作的帖子:
posts_not_by_author_a = Post.objects.exclude(author__name='用户A')
for post in posts_not_by_author_a:
print(f'Title: {post.title}, Author: {post.author.name}')
发布者:LJH,转发请注明出处:https://www.ljh.cool/43387.html