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)
相关推荐
zhangfeng11332 分钟前
python 深度神经网络训练,pytorch ,tensorflow paddle大模型训练中损失突然增大的原因与对策
pytorch·python·dnn
wastec2 分钟前
Python计算机视觉第十章-OpenCV
python·opencv·计算机视觉
huanxiangcoco18 分钟前
207. 课程表
python·leetcode·广度优先
matrixlzp20 分钟前
Python Selenium 自动化爬虫 + Charles Proxy 抓包
爬虫·python·selenium·自动化
子午21 分钟前
水果识别系统Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
人工智能·python·深度学习
卑微的Coder24 分钟前
python画正方形、平行四边形、六边形、五角星、风车(四个半圆)
开发语言·python
bugtraq202126 分钟前
Fyne ( go跨平台GUI )中文文档-绘图和动画(三)
开发语言·后端·golang
一只会敲代码的小灰灰31 分钟前
python学习第十节:爬虫基于requests库的方法
爬虫·python·学习
Adolf_199336 分钟前
Flask-JWT-Extended登录验证
后端·python·flask
2402_857589361 小时前
基于Spring Boot的Java免税商品优选商城设计
java·spring boot·后端