ORM
对象映射关系
:把我们定义的对象(类),,映射到数据库的表中,Django的ORM, 是为了跟SQL语句有同样的表达能力
DateTimeField: True
, Django会默认填充当前时间
choices: 在admin中, 会提供一个下拉列表
数值型
字段
介绍
AutoField int(11)
自增主键: id = models.AutoField(primary_key=True)
BooleanField tinyint(1)
布尔类型字段, 一般用来记录状态标记
DecimalField decimal
指定精确到多少位数: 666.66 => max_digits=5, decimal_places=2
IntegerField int(11)
同AutoFields一样, 但是不自增
PositiveIntegerField
同IntegerField, 但是只包含正整数
SmallIntegerField smallint
小整数时一般用到
字符型
字段
介绍
CharField varchar
基础的varchar类型
URLField
继承自CharField, 但是实现了对URL的特殊处理
UUIDField char(32)
除了PostgreSQL中使用的时UUID类型, 其他都是固定长度char(32), 用来存放生成的唯一ID
EmailField
继承自CharField, 但是实现了对Email的特殊处理
FileField
继承自CharField, 但是实现了对文件的特殊处理
TextField
longtext 继承自FileField, 用来处理图片相关数据, 在展示上会有不同
日期类型
字段
介绍
DateField
对应MySQL中的data
DateTimeField
对应MySQL中的datatime
TimeField
对应MySQL中的data
关系类型
用来关联两张表
多对多会创建一个中间表,来进行多对多的关联
字段
介绍
ForeignKey
OneToOneField
ManyToManyField
参数
字段
介绍
null
用于设定在数据库层面是否允许为空
blank
针对业务层面, 该值是否允许为空
choices
配置之后,在admin页面可以看到对应的可选项展示
db_column
指定Model中的某个字段对应数据库中的哪个字段
db_index
配置索引,作为查询条件的字段
default
默认值配置
editable
是否可编辑, 默认True。如果不想这个字段展示到页面上可以设置False
error_messages
用来自定义字段值校验失败时的异常显示key(null、blank、invalid、incalid_choice、unique、unique_for_date)
help_text
字段提示语,在页面对应字段的下方展示此配置
primary_key
主键,配置后,在页面对字段的下方会展示此配置
unique_for_date
针对date的联合约束,不是数据库层面的约束
unique_for_month
针对月份的联合约束
unique_for_year
针对年份的联合约束
verbose_name
字段对应的展示文案
validators
自定义校验逻辑, 同form
类似
QuerySet
本质是一个懒加载
的对象
可以使用链式调用
: posts = Post.objects.filter(status=1).filter(category_id=2)
posts = Post.objects.all() # 返回一个QuerySet对象,赋值给posts
available_posts = posts.filter(status=1) # 继续返回一个QuerySet对象,并赋值给available_posts
print(available_posts) # 此时根据上面的两个条件执行数据库查询操作,对应:select × from blog_post where status = 1;
支持链式调用的接口
接口
介绍
all
查询所有数据
filter
根据条件过滤数据
exclude
同filter, 只是相反的逻辑
reverse
把QuerySet中的结果倒叙排列
distinct
用来进行去重查询
none
返回空的QuerySet
不支持链式调用
接口
介绍
get
条件查询,存在返回实例,不存则抛出DoesNotExist异常
create
直接常见一个Model对象
get_or_create
根据条件查找,没有,就使用create创建
update_or_create
同get_or_create, 只是用来更新操作
count
返回QuerySet有多少条数据
latest
返回最新的一条记录,但是需要在Meta中定义:get_latest_by = <用来排序的字段>
earliest
同上,返回最早的一条数据
first
从当前QuerySet中获取第一条数据
last
从当前QuerySet中获取最后一条数据
exists
返回True或False
blank_create
同create,批量创建记录
in_blank
批量查询,接收两个参数:id_list, filed_name
update
根据条件批量更新记录:Post.object.filter(owner_name=“asd”).update(title=“更新")
delete
同update,根据条件批量删除数据,update和delete都会触发Django的signal
values
当我们明确知道只需要返回某个字段的值:title_list = Post.obnjects.filter(id=1).values(“title”),返回包含dict的QuerySet
values_list
同values, 但直接返回的是包含tuple
的QuerySet
title_list = Post.objects.filter(category_id=1).values_list("title", flat=True)
for title in title_list:
print(title)
进阶接口
defer:把不需要展示的数据做延迟加载, 比如获取文章除正文外的其他字段: posts = Post.objects.all().defer('content')
, 这样拿到的记录中就不会包含content中的内容
posts = Post.objects.all().defer('content')
for post in posts: # 此时会执行数据库查询
print("post.content") # 此时会执行数据查询, 获取到content
only: 和defer刚好相反, 如果想只获取title中的值,可以使用only
select_related: 可以用来处理一对多
的关系
posts = Post.objects.all()
for post in posts: # 产生数据库查询
print(post.owner) # 产生额外的数据库查询
posts = Post.objects.all().select_related('category')
for post in posts: # 产生数据库查询, category数据也会一次性查询出来
print(post.category)
prefetch_related: 针对多对多
的数据:
posts = Post.objects.all().prefetch_related('tag')
for post in posts: # 产生两条查询语句, 分别查询post 和 tag
print('post.tag.all()')
常用的字段查询
字段
介绍
contains
包含, 用来进行相似查询
icontains
同contains, 只是忽略大小写
exact
精确匹配
iexact
同 exact, 只是忽略大小写
in
指定某个集合: Post.objects.filter(id__in=[1,2])==>
gt
>
gte
>=
lt
<
lte
=<
startswith
以某个字符串开头,
istartswith
同, startswith, 只是忽略带小写
endswith
以某个字符串结尾,
iendswith
同endswith, 只是忽略大小写
rang
范围查询, 多用于时间范围, :created_time_range=(“开始时间”, “结束时间”)
##进阶查询
F
: 执行数据库层面的计算, 从而避免出现竞争状态
post = Post.objects.get(id=1)
post.pv = post.pv + 1
post.save()
from django.db.models import F
post = Post.objects.get(id=1)
post.pv = F('pv') + 1
post.save()
Q
: 或
的关系: select * from tables where id=1 or id =10;
from django.db.models import Q
post = Post.objects.filter(Q(id=1) | Q(id=10))
post = Post.objects.filter(Q(id=1) & Q(id=10))
想得到某个分类下有多少篇文章
category = Category.objects.get(id=1)
posts_count = catecory.posts_count.count()
通过category.post_count访问, 把结果放到category
from django.db.models import Q
# 这相当于是给category动态增加了属性posts_count, (源于Count("post"))
catefories = Category.objects.annotate(post_count = Count("post"))
print(categoies[0].posts_count)
Sum
: 同Count类似,aggregate
, 只是他是用来做合计的, 比如计算所有文章加起来的访问量是多少:
from django.db.models import Sum
post.objects.aggregate(all_pv=Sum("pv")) # 输出结果: {"all_pv": 487}
评论区