Django之模型层

【1】常见的13中查询方法

例子语法:models.Userinfo.objects.filter().all()

|--------------|------------------------|
| 查询方法 | 解释 |
| all() | 查询所有数据 |
| first() | 那queryset中第一条数据 |
| last() | 那最后一条数据 |
| filter() | 带有过滤条件的查询,查询不到结果返回None |
| get() | 带有guolv条件的查询,查询不到结果报错 |
| values() | 指定查询的字段,返回的是列表套字典 |
| value_list() | 指定查询的字段,返回的是列表套元组 |
| distinct() | 去重 |
| order_by() | 排序,默认是升序,降序在条件前面加 "-" |
| count() | 统计有多少条数据 |
| reverse() | 反转,前提是要先排序 |
| exclude() | 排除、 |
| exists() | 判断某个字段存不存在 |

【2】基于下划线的查询

例子语法:models.Userinfo.objects.filter(age__gt=3)

|-----------------|--------------------------------|
| 方法 | 解释 |
| __gt | 大于 |
| __lt | 小于 |
| __gte | 大于等于 |
| __lte | 小于等于 |
| __in | 是,例如(年龄是11) |
| __range | 范围,例如(年龄在18到40岁之间的 首尾都要) |
| __contains | 模糊查询,例如(查询出名字里面含有s的数据 ),区分大小写 |
| __icontains | 模糊查询,例如(查询出名字里面含有s的数据 ),不区分大小写 |
| __startswith | 判断是否以某个字母开头,例如(用户名以s开头的) |
| __endswith | 判断是否以某个字母结尾,例如(用户名以s结尾的) |
| __year,__month等 | 时间 |

【3】一对多外键的增删改查

以Book表为例

【3.1】增:create()
  • models.Book.objects.create(title = ' 西游记 ',price = ' 100 ' publish_id = 1)
    • title:书名、price:价格、publish_id:外键字段
【3.2】删:delete()
  • models.Book.objects.filter(id=1).delete()
    • id:id字段
    • 删除id=1的字段
【3.3】修改:update()
  • models.Book.objects.filter(id=1).update(public_id=2)
    • 将id=1的那条记录的外键id的值改成2

【4】多对多外键的增删改查

以书籍表和作者表为例

【4.1】增:add

第一步:先查

book_obj = models.Book.objects.filter(id=1).first()

print(book_obj.authors) # 到达第三张表

第二步:增加

book_obj.authors.add(1) # 书籍id为1的书籍绑定一个主键为1 的作者

括号内可以传数字也可以是对象,并且都支持多个

【4.2】删:remove

第一步:先查

book_obj = models.Book.objects.filter(id=1).first()

print(book_obj.authors) # 到达第三张表

第二步:删除

book_obj.authors.remove(1) # 删除外键id=1的全部作者

括号内可以传数字也可以是对象,并且都支持多个

【4.3】修改:set

第一步:先查

book_obj = models.Book.objects.filter(id=1).first()

print(book_obj.authors) # 到达第三张表

第二步:增加

book_obj.authors.set([2]) # 书籍id为1的书的原作者改为外键为2的作者

set():括号内必须填一个可迭代对象,该对象既可以是数字也可以是对象,并且都支持多个

【5】正反向的概念(用于多表查询)

正向:拥有外键字段的表去查别的表。---------正向查询按外键字段查询

反向:没有外键字段的表去查有外键字段的表。

反向查询按表名小写查询。如果表名小写查不到就加_set。例如:book_set

【6】多表查询

【6.1】子查询(基于对象的跨表查询)

  • 子查询步骤
    • 1、先判断数据的表关系
    • 2、判断数据的正反向关系
    • 3、写方法

正向例题:

python 复制代码
查询书籍主键为1的出版社
     book_obj = models.Book.objects.filter(pk=1).first()
     # 书查出版社 正向
     res = book_obj.publish
     print(res)
     print(res.name)
     print(res.addr)

基于对象在正向什么时候加 .all()问题:

当查询的结果有多个的时候需要加 .all()


反向例题:

python 复制代码
查询出版社是东方出版社出版的书
     publish_obj = models.Publish.objects.filter(name='东方出版社').first()
    # 出版社查书  反向
     res = publish_obj.book_set  # app01.Book.None
     res = publish_obj.book_set.all()
     print(res)

基于对象在反向什么时候需要加_set.all()

在反向查询的时候,当查询的结果有多个,就需要加_set.all()

【6.2】联表查询(基于双下划线的跨表查询)

  • 联表查询步骤
    • 1、先判断数据的表关系
    • 2、判断数据的正反向关系
    • 3、写方法

例题的正向查询和反向查询的方法

python 复制代码
1.查询jason的手机号和作者姓名

# 正向
res = models.Author.objects.filter(name='jason').values('author_detail__phone','name')
    print(res)

# 反向
res = models.AuthorDetail.objects.filter(author__name='jason').values('phone','author__name')
    print(res)

【6.3】聚合查询:aggregate

集合查询一般配合分组一起使用

聚合查询需要导入 :from.db.models import Max,Min,Avg,Sum,Count

使用方法:

python 复制代码
例子

 # 1 所有书的平均价格
     res = models.Book.objects.aggregate(Avg('price'))
     print(res)
    # 2.上述方法一次性使用
    res = models.Book.objects.aggregate(Max('price'),Min('price'),Sum('price'),Count('pk'),Avg('price'))
    print(res)

【6.4】分组查询:annotate

分组查询特点:

分组之后只能获得分组的依据,其它的字段不能获取。

这是因为设置了严格模式:ONLY_FULL_GROUP_BY

只需要将严格模式的指令去除就行了

例题

python 复制代码
 from django.db.models import Max, Min, Sum, Count, Avg

    # 1.统计每一本书的作者个数

    res = models.Book.objects.annotate(author_num=Count('authors')).values('title','author_num')
 
'''
models点后面的表名,是以Book表分组
 
我们还可以给起别名
 
author_num就是给Count('authors')起别名

'''

分组查询按照指定字段分组:

models.Book.object.values('price').annotate()

如果出现分组查询报错的情况,解决方式:修改严格模式

【7】F和Q查询

【7.1】F查询

F查询作用:能够帮助我们直接获取到表中某个字段对应的数据

F查询需要导入: from django.db.models import F

F查询实例1:

python 复制代码
# 1.查询卖出数大于库存数的书籍

    from django.db.models import F
    res = models.Book.objects.filter(maichu__gt=F('kucun'))
    print(res)

F查询实例2:

python 复制代码
# 3.将所有书的名称后面加上爆款两个字

"""在操作字符类型的数据的时候 F不能够直接做到字符串的拼接"""
# 需要借用Concat方法和Value方法才能实现字符串的拼接

    from django.db.models.functions import Concat
    from django.db.models import Value
    models.Book.objects.update(title=Concat(F('title'), Value('爆款')))

'''如果直接使用F查询,得到的结果是所有的名称都会变成空白'''

    # models.Book.objects.update(title=F('title') + '爆款')  # 所有的名称会全部变成空白

【7.2】Q查询

Q查询将 filter方法括号内默认的and关系查询变换成or关系查询或not关系查询

Q查询默认有3中关系:and、or、not

1、Q包裹用 " ," 分割是 and 关系

例子:

python 复制代码
# 1.查询卖出数大于100或者价格小于600的书籍

from django.db.models import Q

res = models.Book.objects.filter(Q(maichu__gt=100),Q(price__lt=600))  # Q包裹逗号分割 还是and关系

2、Q包裹用" | "分割是 or 关系

python 复制代码
# 1.查询卖出数大于100或者价格小于600的书籍

from django.db.models import Q

res = models.Book.objects.filter(Q(maichu__gt=100)|Q(price__lt=600))  # Q包裹"|"分割 还是and关系

3、Q查询前面加" ~ "就是 not 关系

python 复制代码
# 1.查询卖出数大于100或者价格小于600的书籍

from django.db.models import Q

res = models.Book.objects.filter(~Q(maichu__gt=100)|Q(price__lt=600))

'''
~Q(maichu__gt=100)只是这个条件是 not关系 竖杠后面的条件不是 not关系

~(Q(maichu__gt=100)|Q(price__lt=600):这个才全是not关系

'''

Q查询的高阶用法:能够将查询条件左边也变成字符串的形式

语法:

python 复制代码
 q = Q()
    q.connector = 'or'
    q.children.append(('maichu__gt',100))
    q.children.append(('price__lt',600))
    res = models.Book.objects.filter(q)  # 默认还是and关系
    print(res)
相关推荐
鹏码纵横2 小时前
已解决:java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 异常的正确解决方法,亲测有效!!!
java·python·mysql
仙人掌_lz2 小时前
Qwen-3 微调实战:用 Python 和 Unsloth 打造专属 AI 模型
人工智能·python·ai·lora·llm·微调·qwen3
weixin_985432112 小时前
Spring Boot 中的 @ConditionalOnBean 注解详解
java·spring boot·后端
猎人everest3 小时前
快速搭建运行Django第一个应用—投票
后端·python·django
猎人everest3 小时前
Django的HelloWorld程序
开发语言·python·django
chusheng18404 小时前
2025最新版!Windows Python3 超详细安装图文教程(支持 Python3 全版本)
windows·python·python3下载·python 安装教程·python3 安装教程
别勉.4 小时前
Python Day50
开发语言·python
xiaohanbao094 小时前
day54 python对抗生成网络
网络·python·深度学习·学习
爬虫程序猿5 小时前
利用 Python 爬虫按关键字搜索 1688 商品
开发语言·爬虫·python
英杰.王5 小时前
深入 Java 泛型:基础应用与实战技巧
java·windows·python