Django框架06
双下划线查询
查询年龄大于20的用户:
res = models.User.objects.filter(age__gt=20) print(res) ''' filter括号内的功能不支持逻辑运算符,只支持=; 其拥有独特的表示方法: __gt 大于 __lt 小于 __gte 大于等于 __lte 小于等于
查询年龄是18、22、25的用户:
res = models.User.objects.filter(age__in=[18, 22, 25]) print(res) ''' __in 成员运算 '''
查询年龄在18到26之间的用户:
res = models.User.objects.filter(age__range=[18, 26]) # 包含18和26 print(res) ''' __range 范围查询 ''''
查询姓名中包含字母j的用户:
res = models.User.objects.filter(name__contains='j') res = models.User.objects.filter(name__icontains='j') print(res) ''' __contains 区分大小写 __icontains 忽略大小写 '''
查询月份与年份数据:
# 查询月份是5月的数据 res = models.User.objects.filter(op_time__month=5) print(res) # 查询年份是22年的数据 res = models.User.objects.filter(op_time__year=2022) print(res) ''' __year 按照年份筛选数据 __month 按照月份筛选数据 '''
其它的双下方法:
''' 使用属性+__startswith可以判断属性由某字符串开始的行 使用属性+__endswith可以判断属性由某字符串结束的行 __regex正则 '''
Django使用orm创建表关系
Django当中的orm创建表关系和MySQL当中的表关系类似,也是创建外键,通过外键来连接表与表之间的关系。
表的关系也是分为三种:一对多、一对一和多对多三种关系。
1、关联的表之间建议建立外键,但可以取消关联关系(db_constraint=False)
2、关联表之间的外键字段建议采用对应类名的全小写
3、采用关联表的主键或对象均能进行操作
- 一对多关系:
''' 1. 关系中 『多』 依赖于 『一』 2. Django 1.x外键关联默认有级联删除,2.x需要手动明确外键的级联删除(on_delete=models.CASCADE) '''
''' eg: 书与出版社 一本书不能对应多个出版社 一个出版社可以对应多本书 # 一对多关系 书是多 出版社是一
ps:Django orm的外键字段,针对一对多关系,也是建在多的一方!!!
- 一对一关系:
''' 1.通过外键所在表决定依赖关系; 2.Django orm外键字段针对一对一关系,需要建在查询频率较高的表中 '''
''' eg: 作者与作者详情 一个作者不能对应多个作者详情 一个作者详情不能对个多个作者 '''
- 多对多关系:
''' 1.多对多关系存在关系表,关系表建议采用ManyToManyField字段处理 2.需要手动创建关系表时,在字段中明确through与through_field值 '''
''' eg: 书与作者 一本书可以对应多个作者 一个作者可以对应多本书 '''
ps:Django orm外键字段针对多对多关系,可以不用自己创建第三张表!!!
''' ManyToManyField不会在表中创建实际的字段,而是告诉django orm自动创建第三张关系表 ForeignKey、OneToOneField会在字段的后面自动添加_id后缀;如果你在定义模型类的时候自己添加了该后缀,那么迁移的时候还会再次添加_id_id;所以不要自己加_id后缀 '''
外键字段的操作
- 一对多和一对一字段操作:
''' 增 publish_id=1 author_detail_id=1 publish=publish_obj author_detail=detail_obj 改 update(publish_id=3) update(author_detail_id=3) update(publish=publish_obj) update(author_detail=detail_obj) '''
- 多对多字段操作:
''' 1.第三张关系表创建数据 book_obj = models.Book.objects.filter(pk=1).first() book_obj.authors.add() 括号内可以放主键值也可以放数据对象,并且都支持多个 2.第三张关系表修改数据 book_obj.authors.set() 括号内必须是一个可迭代对象,元素同样支持主键值或者数据对象 3.第三张关系表删除数据 book_obj.authors.remove() 括号内可以放主键值也可以放数据对象 并且都支持多个 4.第三张关系表清空指定数据 book_obj.authors.clear() 括号内无需传值 直接清空当前表在第三张关系表中的绑定记录 '''
多表查询的思路
''' MySQL多表查询思路: 1.子查询 将SQL语句用括号括起来当做条件使用 2.连表操作 inner join\left join\right join\union django orm本质还是使用的上述两种方法 1.子查询>>>:基于对象的跨表查询 2.连表操作>>>:基于双下划线的跨表查询 '''
正向反向概念:
正反向概念的核心在于当前数据对象是否含有外键字段,有则是正向,没有则是反向。
''' 正向: eg: 由书籍查询出版社 外键字段在书籍表中 那么书查出版社就是'正向' 由书籍查询作者 外键字段在书籍表中 那么书查作者就是'正向' 由作者查询作者详情 外键字段在作者表中 那么也是'正向' 反向: eg: 由出版社查询书籍 外键字段不在出版社表 那么出版社查书就是'反向' '''
note:
''' 正向反向概念:从存放外键的表到关系表称之为正向跨表查询,反之称之为逆向查询 正向查询通过外键属性名进行跨表查询 反向查询通过关联表对应表名小写进行跨表查询 '''
基于对象的跨表查询和基于双下划线的跨表查询需要用到正反向查询。
基于对象的跨表查询
基于对象的跨表查询本质就是子查询,即分步操作即可。
基于对象的跨表查询需要用到正反向查询。
# 1.查询数据分析书籍对应的出版社 # 先获取书籍对象 book_obj = models.Book.objects.filter(title='数据分析').first() # 再使用跨表查询 res = book_obj.publish print(res) # 出版社对象:北方出版社 # 2.查询python全栈开发对应的作者 # 先获取书籍对象 book_obj = models.Book.objects.filter(title='python全栈开发').first() # 再使用跨表查询 res = book_obj.authors # app01.Author.None res = book_obj.authors.all() print(res) # <QuerySet [<Author: 作者对象:jason>, <Author: 作者对象:jerry>]> # 3.查询作者jason的详情信息 # 先获取jason作者对象 author_obj =models.Author.objects.filter(name='jason').first() # 再使用跨表查询 res = author_obj.author_detail print(res) # 作者详情对象:芜湖 # 4.查询东方出版社出版的书籍 publish_obj = models.Publish.objects.filter(name='东方出版社').first() res = publish_obj.book_set # app01.Book.None res = publish_obj.book_set.all() print(res) # <QuerySet [<Book: 书籍对象:linux云计算>, <Book: 书籍对象:聊斋志异>]> # 5.查询jason编写的书籍 author_obj =models.Author.objects.filter(name='jason').first() res = author_obj.book_set # app01.Book.None res = author_obj.book_set.all() print(res) # <QuerySet [<Book: 书籍对象:golang高并发>, <Book: 书籍对象:python全栈开发>]> # 6.查询电话是110的作者 author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first() res = author_detail_obj.author print(res) # 作者对象:jason
基于双下划线的跨表查询
基于双下划线的跨表查询的本质就是连表操作。
基于双下划线的跨表查询需要用到正反向查询。
# 查询数据分析书籍对应的价格和出版日期 models.Book.objects.filter(title='数据分析').values('price','publish_time') '''手上有什么条件就先拿models点该条件对应的表名''' # 1.查询数据分析书籍对应的出版社名称 res = models.Book.objects.filter(title='数据分析').values('publish__name', 'publish__addr') print(res) # <QuerySet [{'publish__name': '北方出版社', 'publish__addr': '北京'}]> # 2.查询python全栈开发对应的作者姓名和年龄 res = models.Book.objects.filter(title='python全栈开发').values('authors__name','authors__age') print(res) # <QuerySet [{'authors__name': 'jason', 'authors__age': 18}, {'authors__name': 'jerry', 'authors__age': 29}]> # 3.查询作者jason的手机号和地址 res = models.Author.objects.filter(name='jason').values('author_detail__phone','author_detail__addr') print(res) # <QuerySet [{'author_detail__phone': 110, 'author_detail__addr': '芜湖'}]> # 4.查询东方出版社出版的书籍名称和价格 res = models.Publish.objects.filter(name='东方出版社').values('book__title','book__price') print(res) # <QuerySet [{'book__title': 'linux云计算', 'book__price': Decimal('24888.44')}, {'book__title': '聊斋志异', 'book__price': Decimal('16987.22')}]> # 5.查询jason编写的书籍名称和日期 res = models.Author.objects.filter(name='jason').values('book__title', 'book__publish_time') print(res) # <QuerySet [{'book__title': 'golang高并发', 'book__publish_time': datetime.date(2022, 6, 7)}, {'book__title': 'python全栈开发', 'book__publish_time': datetime.date(2022, 2, 28)}]> # 6.查询电话是110的作者的姓名和年龄 res= models.AuthorDetail.objects.filter(phone=110).values('author__name','author__age') print(res) # <QuerySet [{'author__name': 'jason', 'author__age': 18}]>
双下划线查询扩展
"""基于双下划线的跨表查询的结果也可以是完整的数据对象""" '''手上有条件所在的表可以不被models点 直接点最终的目标数据对应的表''' # 1.查询数据分析书籍对应的出版社名称 # res = models.Publish.objects.filter(book__title='数据分析') # print(res) # <QuerySet [<Publish: 出版社对象:北方出版社>]> # res = models.Publish.objects.filter(book__title='数据分析').values('name') # print(res) # <QuerySet [{'name': '北方出版社'}]> # 2.查询python全栈开发对应的作者姓名和年龄 # res = models.Author.objects.filter(book__title='python全栈开发').values('name','age') # print(res) # <QuerySet [{'name': 'jason', 'age': 18}, {'name': 'jerry', 'age': 29}]> # 3.查询作者jason的手机号和地址 # res = models.AuthorDetail.objects.filter(author__name='jason').values('phone','addr') # print(res) # <QuerySet [{'phone': 110, 'addr': '芜湖'}]> # 4.查询东方出版社出版的书籍名称和价格 # res = models.Book.objects.filter(publish__name='东方出版社').values('title','price') # print(res) # <QuerySet [{'title': 'linux云计算', 'price': Decimal('24888.44')}, {'title': '聊斋志异', 'price': Decimal('16987.22')}]> # 5.查询jason编写的书籍名称和日期 # res = models.Book.objects.filter(authors__name='jason').values('title','publish_time') # print(res) # <QuerySet [{'title': 'golang高并发', 'publish_time': datetime.date(2022, 6, 7)}, {'title': 'python全栈开发', 'publish_time': datetime.date(2022, 2, 28)}]> # 6.查询电话是110的作者的姓名和年龄 # res = models.Author.objects.filter(author_detail__phone=110).values('name','age') # print(res) # <QuerySet [{'name': 'jason', 'age': 18}]>
连续跨表操作
# 查询python全栈开发对应的作者的手机号 # res = models.Book.objects.filter(title='python全栈开发').values('authors__author_detail__phone') # print(res) # <QuerySet [{'authors__author_detail__phone': 110}, {'authors__author_detail__phone': 140}]> res1 = models.AuthorDetail.objects.filter(author__book__title='python全栈开发').values('phone') print(res1) # <QuerySet [{'phone': 110}, {'phone': 140}]>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?