外键字段的增删改查
# 前期数据表准备
# 以图书 出版社 作者 作者详情表为例
# 1. 针对一对多,一对一
# 增加数据,增加一本书
# models.Book.objects.create(title='西游记', price=100, publish_time='2022-02-01', publish_id=1)
# 先查询出你要添加的出版社对象
# publish_obj = models.Publish.objects.filter(pk=2).first()
# models.Book.objects.create(title='西游记1', price=100, publish_time='2022-02-01', publish=publish_obj)
# 第二种方式
# book_obj = models.Publish.objects.filter(pk=2).first()
# book_obj.publish.add(1)
# 2. 改
# models.Book.objects.filter(pk=1).update(publish_id=2)
# book_obj = models.Book.objects.filter(pk=1).first()
# print(book_obj.publish) #
# publish_obj = models.Publish.objects.filter(pk=1).first()
# models.Book.objects.filter(pk=1).update(publish=publish_obj)
# 针对多对多
# 给一本书添加多个作者
book_obj = models.Book.objects.filter(pk=1).first()
# print(book_obj.authors) # app01.Author.None
# print(book_obj.authors.all()) # app01.Author.None
# 增加
# book_obj.authors # 代表已经到第三张表了
# book_obj.authors.add(1)
# 支持对象
# author_obj1 = models.Author.objects.filter(pk=1).first()
# author_obj2 = models.Author.objects.filter(pk=2).first()
# book_obj.authors.add(1, 2)
# book_obj.authors.add(author_obj1, author_obj2)
# 改
# book_obj.authors.set([3, 2])
# book_obj.authors.set([author_obj1, author_obj2])
# 删除
book_obj.authors.remove(2)
# 清空
book_obj.authors.clear()
正反向查询
正向查询
反向查询
'''
外键字段在我手上,我查你就是正向
外键字段不再我手上,我查你就是反向
'''
eg:
book >>> publish # 正向
publish >>> book # 反向
author >>> book # 反向
book >>> author # 正向
在多表查询的时候,按照正反向查询口诀
'''
1. 正向查询按照字段(外键字段)
2. 反向查询按照表名小写或者表名小写_set.all()
'''
基于对象的跨表查询(子查询)
###############################跨表查询###########################################
# 1.
# 查询书籍主键为1的出版社
# 书 >>> 出版社 >>> 正向
# book_obj = models.Book.objects.filter(pk=1).first()
# print(book_obj)
# print(book_obj.publish) # 代表的是出版社对象
# print(book_obj.publish.name)
# print(book_obj.publish.addr)
# 2.
# 查询书籍主键位1的作者
# book >>> author >>> 正向
# book_obj = models.Book.objects.filter(pk=1).first()
# print(book_obj.authors) # app01.Author.None
# print(book_obj.authors.all()) # app01.Author.None
# for author_obj in book_obj.authors.all():
# print(author_obj.name)
# 3.
# 查询tom的手机号
# 作者 >>> 作者详情 >>> 正向
# author_obj = models.Author.objects.filter(name='tom').first()
# print(author_obj.author_detail)
# print(author_obj.author_detail.phone)
# 4.
# 查询东京出版社出版的书籍
# 出版社查书 >>> 反向
# publish_obj = models.Publish.objects.filter(name='东京出版社').first()
# print(publish_obj.book_set) # app01.Book.None
# print(publish_obj.book_set.all()) # app01.Book.None
# for book_obj in publish_obj.book_set.all():
# print(book_obj.title)
# 5.
# 查询tom写过的书
# 作者查书 >>> 反向
author_obj = models.Author.objects.filter(name='tom').first()
print(author_obj.book_set.all())
# 6.
# 查询手机号是120的作者姓名
# 作者详情查作者信息 >>> 反向
author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first()
print(author_detail_obj.author) #
'''
总结:
反向查询只要查询出的结果可能有多个的时候,都要加上 表名_set.all()
如果查询出来的结果是一个,就不用加_set,直接使用表名小写
'''
基于双下划线的跨表查询
# 1.
# 查询书籍主键为1的出版社名称和书籍名称
'''
正反向查询的概念同样适用
'''
# res = models.Book.objects.filter(pk=1).values('title', 'publish__name')
# print(res)
# 2.
# 查询书籍主键位1的作者名称
# res = models.Book.objects.filter(pk=1).values('authors__name')
# print(res)
# 3.
# 查询tom的手机号
# res = models.Author.objects.filter(name='tom').values('author_detail__phone')
# print(res)
# 4.
# 查询东京出版社出版的书籍
# res = models.Publish.objects.filter(name='东京出版社').values('book__title')
# print(res)
# 5.
# 查询tom写过的书
# res = models.Author.objects.filter(name='tom').values('book__title')
# print(res)
# 6.
# 查询手机号是120的作者姓名
# res = models.AuthorDetail.objects.filter(phone=120).values('author__name')
# print(res)
# 7.
# 查询书籍主键位1的作者的手机号
# book author author_detail
res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
print(res)
F查询和Q查询
# F查询
可以拿到数据库中原有的数据
# 1. 把书籍的价格在原来的基础之上加100元
book
update book set price = price + 100 where id=1;
# F查询
# 1. 把书籍的价格在原来的基础之上加100元
'''
一般来说,跟数据相关的模块要么在django.db,要么在django.db.models
'''
from django.db.models import F
''' F查询默认是对数字类型的'''
# models.Book.objects.update(price=F('price')+100)
from django.db.models.functions import Concat
from django.db.models import Value
# 2.
# models.Book.objects.update(title=Concat(F('title'), Value('东京出版社')))
# Q查询
# 1. 查询书籍价格大于等于300的或者id=1的数据
# sql: select * from t where price >= 300 or id=1
# orm:
from django.db.models import Q
# res=models.Book.objects.filter(Q(price__gte=300), Q(id=1)) # 逗号分隔,还是and关系
# res=models.Book.objects.filter(Q(price__gte=300)| Q(id=1)) # |分隔,还是or关系
# res=models.Book.objects.filter(~Q(price__gte=300)| ~Q(id=1)) # ~分隔,取反
# print(res)
# q = 'price'