Django的多表查询操作实战
作者:乔治我的M4呢?
1 > 神奇的双下划线查询
1 > 查询年龄大于20的用户
res = modles.User.objects.filter(age__gt=20) print(res) ''' __gt 大于 __lt 小于 __gte 大于等于 __lte 小于等于 '''
2 > 查询年龄是18、22、25的用户
res = modles.User.objects.filter(age__in=[18, 22, 25]) print(res) ''' __in 成员运算 '''
3 > 查询年龄在18到26之间的用户
res = modles.User.objects.filter(age__ranger=[18, 26]) print(res) ''' __ranger 范围查询 '''
4 > 查询姓名中包含字母j的用户
res = modles.User.objects.filter(name__contains='j') res = modles.User.objects.filter(name__icontains='j') print(res) ''' __contains 区分大小写 __icontains 忽略区分大小写 '''
5 > 其他方法补充
__startswith 以什么开头
__endswith 以什么结尾
__regex 正则
6 > 查询月份是5月的数据
res = models.User.objects.filter(op_time__month=5) print(res) ''' __year 按照年份筛选数据 __month 按照月份筛选数据 '''
2 > 外键字段的创建
MySQL复习
关系的种类
一对多关系
多对多关系
一对一关系
关系的判断
换位思考
字段的位置
一对多关系 外键字段建在多的一方
多对多关系 外键字段建在第三张关系表中
一对一关系 外键字段建在任意一方都可以 但是推荐建在查询频率较高的表中
2.1 > 数据准备
django orm创建表关系 图书表 出版社表 作者表 作者详情表 关系判断 书与出版社 一本书不能对应多个出版社 一个出版社可以对应多本书 # 一对多关系 书是多 出版社是一 ForeignKey '''django orm外键字段针对一对多关系也是建在多的一方 ''' 书与作者 一本书可以对应多个作者 一个作者可以对应多本书 # 多对多关系 ManyToManyField '''django orm外键字段针对多对多关系 可以不用自己创建第三张表''' 作者与作者详情 一个作者不能对应多个作者详情 一个作者详情不能对个多个作者 # 一对一关系 OneToOneField '''django orm外键字段针对一对一关系 建在查询频率较高的表中''' 注意事项: ''' ManyToManyField不会在表中创建实际的字段 而是告诉django orm自动创建第三张关系表 ForeignKey、OneToOneField会在字段的后面自动添加_id后缀 如果你在定义模型类的时候自己添加了该后缀那么迁移的时候还会再次添加_id_id 所以不要自己加_id后缀 ''' 关键字里面的参数说明 to: 用于指定跟哪张表有关系 自动关联主键 to_field\to_fields: 也可自己指定关联字段
2.2 > 代码创建
from django.db import models
# Create your models here.
class Book(models.Model):
"""图书表"""
title = models.CharField(max_length=32, verbose_name='书名')
price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name='价格')
publish_time = models.DateTimeField(auto_now_add=True, verbose_name='出版日期')
# 书与出版社的外键字段 一对多
publish = models.ForeignKey(to='Publish')
# 书与作者的外键字段 多对多
authors = models.ManyToManyField(to='Author')
def __str__(self):
return '书籍对象:%s' % self.title
class Publish(models.Model):
"""出版社"""
name = models.CharField(max_length=32, verbose_name='出版社名称')
addr = models.CharField(max_length=32, verbose_name='出版社地址')
def __str__(self):
return '出版社对象:%s' % self.name
class Author(models.Model):
"""作者表"""
name = models.CharField(max_length=32, verbose_name='作者姓名')
age = models.IntegerField(verbose_name='年龄')
# 作者与作者详情外键字段 一对一
author_detail = models.OneToOneField(to='AuthorDetail')
def __str__(self):
return '作者对象:%s' % self.name
class AuthorDetail(models.Model):
"""作者详情"""
phone = models.BigIntegerField(verbose_name='手机号')
addr = models.CharField(max_length=64, verbose_name='家庭地址')
def __str__(self):
return '地址详情对象:%s' % self.addr
'''
运行数据库迁移命令
makemigrations
migrations
'''
3 > 外键字段操作
3.1 > 一对多、一对一外键字段操作
增加数据 models.Book.objects.create(title='聊斋志异',price=1699.80,publish_id=1) ''' publish_id=1 author_detail_id=1 ''' publish_obj = models.Publish.objects.filter(pk=2).first() models.Book.objects.create(title='资本论',price=9566.02,publish=publish_obj) ''' publish=publish_obj author_detail=detail_obj ''' 修改数据 models.Book.objects.filter(pk=11).update(publish_id=2) ''' update(publish_id=3) update(author_detail_id=3) ''' publish_obj = models.Publish.objects.filter(pk=1).first() models.Book.objects.filter(pk=11).update(publish=publish_obj) ''' update(publish=publish_obj) update(author_detail=detail_obj) '''
3.2 > 多对多字段操作
主要知识点:
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()
括号内无需传值 直接清空当前表在第三张关系表中的绑定记录
操做代码如下:
book_obj = models.Book.objects.filter(pk=7).first()
# 给多对多虚拟关键表添加关系
# book_obj.authors.add(2)
authors_obj = models.Author.objects.filter(pk=2).first()
authors_obj1 = models.Author.objects.filter(pk=3).first()
book_obj.authors.add(authors_obj1, authors_obj)
# 修改关系
book_obj = models.Book.objects.filter(pk=11).first()
book_obj.authors.set([3, 6])
authors_obj1 = models.Author.objects.filter(pk=6).first()
authors_obj2 = models.Author.objects.filter(pk=7).first()
book_obj.authors.set([authors_obj2,authors_obj1])
# 删除数据
book_obj = models.Book.objects.filter(pk=11).first()
book_obj.authors.remove(6,7)
authors_obj = models.Author.objects.filter(pk=6).first()
book_obj.authors.remove(authors_obj)
# 清空数据
book_obj.authors.clear()4 > 多表查询
MySQL多表查询思路
子查询
将SQL语句用括号括起来当做条件使用
连表操作
inner join\left join\right join\union
django orm本质还是使用的上述两种方法
子查询>>>:基于对象的跨表查询
连表操作>>>:基于双下划线的跨表查询
4.1 > 正反向的概念
核心在于当前数据对象是否含有外键字段 有则是正向 没有则是反向
正向:
eg:
由书籍查询出版社 外键字段在书籍表中 那么书查出版社就是'正向'
由书籍查询作者 外键字段在书籍表中 那么书查作者就是'正向'
由作者查询作者详情 外键字段在作者表中 那么也是'正向'反向
eg:
由出版社查询书籍 外键字段不在出版社表 那么出版社查书就是'反向'
"""
查询口诀
正向查询按外键字段名
反向查询按表名小写
"""
4.2 > 基于对象的跨表查询
操做代码如下:
"""基于对象的跨表查询本质就是子查询即分步操作即可"""
# 1.查询数据分析书籍对应的出版社(正向 一对多)
# book_obj = models.Book.objects.filter(pk=11).first()
# res = book_obj.publish
# print(res)
# 2.查询python全栈开发对应的作者(正向 多对多)
# book_obj = models.Book.objects.filter(pk=11).first()
# res = book_obj.authors.all()
# print(res)
# 3.查询作者jason的详情信息(正向 多对多)
# authors_obj = models.Author.objects.filter(name='jason').first()
# res = authors_obj.author_detail
# print(res)
# 4.查询东方出版社出版的书籍(反向 多对多)
# publish_obj = models.Publish.objects.filter(name='东方出版社').first()
# res = publish_obj.book_set.all()
# print(res)
# 5.查询jason编写的书籍(反向 多对多)
# authors_obj = models.Author.objects.filter(name='jason').first()
# res = authors_obj.book_set.all()
# print(res)
# 6.查询电话是110的作者(反向 一对一)
# authors_detail_obj = models.AuthorDetail.objects.filter(phone='110').first()
# res = authors_detail_obj.author
# print(res)4.3 > 基于双下划线的跨表查询
"""基于双下划线的跨表查询本质就是连表操作"""
# 基于双下划线的跨表查询
"""
查询数据分析书籍对应的价格和出版日期
models.Book.objects.filter(title='数据分析').values('price','publish_time')
"""
'''手上有什么条件就先拿models点该条件对应的表名'''
# 1.查询数据分析书籍对应的出版社名称
# res = models.Book.objects.filter(title='数据分析').values('publish__name')
# print(res)
# 2.查询python全栈开发对应的作者姓名和年龄
# res = models.Book.objects.filter(title='python').values('authors__age','authors__name')
# print(res)
# 3.查询作者jason的手机号和地址
# res = models.Author.objects.filter(name='jason').values('author_detail__phone','author_detail__addr')
# print(res)
# 4.查询东方出版社出版的书籍名称和价格
# res = models.Publish.objects.filter(name='东方出版社').values('book__title','book__price')
# print(res)
# 5.查询jason编写的书籍名称和日期
# res = models.Author.objects.filter(name='jason').values('book__title','book__publish_time')
# print(res)
# 6.查询电话是110的作者的姓名和年龄
# res = models.AuthorDetail.objects.filter(phone='110').values('author__name','author__age')
# print(res)4.4 > 双下线查询扩展
1.查询数据分析书籍对应的出版社名称
res = models.Publish.objects.filter(book__title='数据分析').values('name')
print(res)
# 2.查询python全栈开发对应的作者姓名和年龄
res = models.Author.objects.filter(book__title='python').values('name', 'age')
print(res)
# 3.查询作者jason的手机号和地址
res = models.AuthorDetail.objects.filter(author__name='jason').values('phone', 'addr')
print(res)
# 4.查询东方出版社出版的书籍名称和价格
res = models.Book.objects.filter(publish__name='东方出版社').values('title', 'price')
print(res)
# 5.查询jason编写的书籍名称和日期
res = models.Book.objects.filter(authors__name='jason').values('title', 'publish_time')
print(res)
# 6.查询电话是110的作者的姓名和年龄
res = models.Author.objects.filter(author_detail__phone='110').values('name', 'age')
print(res)
# 连续跨表操作
# 查询python全栈开发对应的作者的手机号
res = models.AuthorDetail.objects.filter(author__book__title='python').values('phone')
print(res)
res = models.Book.objects.filter(title='python').values('authors__author_detail__phone')
print(res)
"""
可能出现的不是疑问的疑问:如何获取多张表里面的字段数据
res = models.Book.objects.filter(title='python全栈开发').values('authors__author_detail__phone','authors__name','title')
print(res)
"""4.5 > 如何查看SQL语句
方式1:如果结果集对象是queryset 那么可以直接点query查看
方式2:配置文件固定配置
适用面更广 只要执行了orm操作 都会打印内部SQL语句
总结
到此这篇关于Django的多表查询操作实战的文章就介绍到这了,更多相关Django多表查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
