模型层字段-多表查询-神奇的双下划线查询-F,Q查询
Django ORM中常用的字段和参数
常用字段
AutoField
int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。
IntegerField
一个整数类型,范围在 -2147483648 to 2147483647。(一般不用它来存手机号(位数也不够),直接用字符串存,)
CharField
字符类型,必须提供max_length参数, max_length表示字符长度。
DateField
日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。
DateTimeField
日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。
TextField(Field)
- 文本类型
用来存大段文本
FileField(Field)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 用户上传的文件会自动放到等号后面指定的文件路径中
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
书写格式一般如下:
自定义对应于数据库的char类型
然后在model.py里建表模型的时候可以直接应用:
字段参数
null
用于表示某个字段可以为空。
unique
如果设置为unique=True 则该字段在此表中必须是唯一的 。
db_index
如果db_index=True 则代表着为此字段设置索引。
default
为该字段设置默认值。
DateField和DateTimeField
auto_now_add
配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。
auto_now
配置上auto_now=True,每次更新数据记录的时候会更新该字段。
关系字段
ForeignKey
外键类型在ORM中用来表示外键关联关系,一般把ForeignKey字段设置在 '一对多'中'多'的一方。
ForeignKey可以和其他表做关联关系同时也可以和自身做关联关系。
字段参数
to
设置要关联的表
to_field
设置要关联的表的字段
on_delete
当删除关联表中的数据时,当前表与其关联的行的行为。
models.CASCADE
删除关联数据,与之关联也删除
db_constraint
是否在数据库中创建外键约束,默认为True。
常用的多表关系查询的外键字段创建
1 2 3 | 一对一字段:OneToOneField 多对多字段:ManyToManyField 一对多字段:ForeignKey |
针对外键字段
当你在使用django2.x版本的时候,建外键字段时,需要手动添加几个关键字段参数
1 2 | models.cascade db_constraints |
Django终端打印SQL语句
把参数放在settings.py配置文件中,会在终端打印出相应的mysql查询语句
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }
配置好之后,再执行任何对数据库进行操作的语句时,会自动将Django执行的sql语句打印到pycharm终端上
也可以用.query大方式查看查询语句:
13个必会操作总结
返回QuerySet对象的方法有
all()
filter()
exclude()
order_by()
reverse()
distinct()
特殊的QuerySet
values() 返回一个可迭代的字典序列
values_list() 返回一个可迭代的元祖序列
返回具体对象的
get()
first()
last()
返回布尔值的方法有:
exists()
返回数字的方法有
count()
神奇的双下滑查询
对应MySQL的查询语句形成对比记忆,方法和查询的方法类似
# 价格 大于 小于 大于等于 小于等于 filter(price__gt='90') filter(price__lt='90') filter(price_gte='90') filter(price_lte='90') # 存在与某几个条件中 filter(price__in=['11','22','33']) # 在某个范围内 filter(price__range=[50,90]) # 模糊查询 filter(title__contains='西') filter(title__icontains='P') # 以什么开头 以什么结尾 # 按年查询 filter(create_time__year='2017')
多表查询:跨表查询,连表查询
书写测试代码脚本:
一对多的字段的增删改查
增操作:关键字 create
改操作:关键字 update
查数据:常用的13种
# < 1 > all(): 查询所有结果
# < 2 > filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
# < 3 > get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,
# 如果符合筛选条件的对象超过一个或者没有都会抛出错误。(源码就去搂一眼~诠释为何只能是一个对象) # < 4 > exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 # < 5 > order_by(*field): 对查询结果排序('-id') / ('price') # < 6 > reverse(): 对查询结果反向排序 >> > 前面要先有排序才能反向
# < 7 > count(): 返回数据库中匹配查询(QuerySet) # 的对象数量。 # < 8 > first(): 返回第一条记录 # < 9 > last(): 返回最后一条记录 # < 10 > exists(): 如果QuerySet包含数据,就返回True,否则返回False # < 11 > values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 # model的实例化对象,而是一个可迭代的字典序列
# < 12 > values_list(*field): 它与values()
# 非常相似,它返回的是一个元组序列,values返回的是一个字典序列
# < 13 > distinct(): 从返回结果中剔除重复纪录 # # 必须完全一样才可以去重(意味着带了id就没有意义了) # # res = models.Book.objects.all().values('name').distinct() 先查一个重复的值再去重
# 查询书籍名字中包含p的
"""原生sql语句 模糊匹配
like % _
"""
# res = models.Book.objects.filter(title__contains='p') # 仅仅只能拿小写p
# res = models.Book.objects.filter(title__icontains='p') # 忽略大小写
删除操作: delete
多对多字段的增删改查
增操作:add()
add():添加操作,括号内既可以传数字也可以传对象,并且支持一次性传多个,逗号隔开即可
改操作:set()
set()括号内需要传一个可迭代对象,可迭代对象中,可以是多个数字组合,也可以是多个对象组合,但不能 混合使用
删除操作:remove()
remove() 括号内既可以传数字,也可以传对象,并且支持传多个,逗号隔开即可.
清空操作:clear(),括号内不需要传任何参数
跨表查询
1.对象查找(跨表)
语法:
对象.关联字段.字段
要点:先拿到对象,再通过对象去查对应的外键字段,分两步
示例:
book_obj = models.Book.objects.first() # 第一本书对象(第一步) print(book_obj.publisher) # 得到这本书关联的出版社对象 print(book_obj.publisher.name) # 得到出版社对象的名称
2.字段查找(跨表)
语法:
关联字段__字段
要点:利用Django给我们提供的神奇的双下划线查找方式
1 2 | models.Book.objects. all ().values( "publisher__name" ) #拿到所有数据对应的出版社的名字,神奇的下划线帮我们夸表查询 |
反向操作(两种方式)
1.对象查找
语法:
obj.表名_set
要点:先拿到外键关联多对一,一中的某个对象,由于外键字段设置在多的一方,所以这里还是借用Django提供的双下划线来查找
1 2 3 | publisher_obj = models.Publisher.objects.first() # 找到第一个出版社对象 books = publisher_obj.book_set. all () # 找到第一个出版社出版的所有书 titles = books.values_list( "title" ) # 找到第一个出版社出版的所有书的书名 |
正向与反向的概念
口诀"正向查询按外键字段,反向查询按表名小写"
# 跨表查询(***) """ 正向与反向的概念 # 一对一 # 正向:author---关联字段在author表里--->authordetail 按字段 # 反向:authordetail---关联字段在author表里--->author 按表名小写 # 一对多 # 正向:book---关联字段在book表里--->publish 按字段 # 反向:publish---关联字段在book表里--->book 按表名小写_set.all() 因为一个出版社对应着多个图书 # 多对多 # 正向:book---关联字段在book表里--->author 按字段 # 反向:author---关联字段在book表里--->book 按表名小写_set.all() 因为一个作者对应着多个图书 正向查询按外键字段 反向查询按表名小写 """ """基于对象的跨表查询(子查询:将一张表的查询结果当做另外一个查询语句的条件)""" """
例题:
1.查询书籍id是1 的出版社名称
1 2 3 | book_obj = models.Book.objects. filter (pk = 1 ).first() print (book_obj.publish.name) print (book_obj.publish.addr) |
2、查询书籍id是2 的作者姓名
# book_obj = models.Book.objects.filter(pk=2).first() print(book_obj.authors) # app01.Author.None # print(book_obj.authors.all()) # res = book_obj.authors.all() # for r in res: # print(r.name)
3、查询出版社是东方出版社出版的书籍
publish_obj = models.Publish.objects.filter(name='东方出版社').first() print(publish_obj.book_set) # app01.Book.None print(publish_obj.book_set.all())
4、查询电话号码是130的作者姓名
author_detail_obj = models.AuthorDetail.objects.filter(phone=130).first()
print(author_detail_obj.author.name) print(author_detail_obj.author.age)
当你反向查询的结果是多个的时候 就需要加_set,否则直接表明小写即可
基于双下划线的跨表查询(连表操作)
联想MySQL:left join 左连接,inner join 内连接,right 右连接,union 全连接
1、查询jason作者的手机号
2、查询手机号是130的作者年龄
3、查询书籍id=1的作者的电话号码
4、查询北方出版社出版的价格大于19的书
聚合查询
关键字:aggregate ,类似mysql的聚合函数,最大值,最小值,平均值,总计,sum(总数)
1 | from django.db.models import Max , Min ,Count,Avg, Sum |
1、统计所有书的总价格
分组查询
结合聚合函数+()使用,关键字:annotate
1、统计每一本书的作者个数
2、统计出每个出版社卖的最便宜的书的价格
3、统计不止一个作者的图书
F查询:
F是个模块,需要导入使用
F查询的本质就是从数据库中获取某个字段的值来进行一系列的操作
1、查询库存数大于卖出的书籍
2、将书籍库存数全部增加100
3、把所有书名后面加上“新款“
拼接需要导入模块:Conact、Value
Q查询:
Q也是一个模块需要导入,才能使用
进行与或非等复杂的组合操作( |,&,&~Q,~(非))
filter() 等方法中逗号隔开的条件是与的关系。 如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象。
例子:查询书籍名称是三国演义或者价格是444.44
Q的高级用法:
更改查询中的条件,用q.connector修改括号内的属性
本文来自博客园,作者:游走De提莫,转载请注明原文链接:https://www.cnblogs.com/Gaimo/p/11553220.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律