" name="sm-site-verification"/>
侧边栏壁纸
博主头像
PySuper博主等级

千里之行,始于足下

  • 累计撰写 203 篇文章
  • 累计创建 14 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录
Web

Django Model层

PySuper
2019-10-29 / 0 评论 / 0 点赞 / 25 阅读 / 12038 字
温馨提示:
所有牛逼的人都有一段苦逼的岁月。 但是你只要像SB一样去坚持,终将牛逼!!! ✊✊✊

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))
  • Count: 用来做聚合查询, annotate

想得到某个分类下有多少篇文章

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}
0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区