065.django之多表查询

it2023-09-27  76

文章目录

一 创建模型(一) 模型创建(二) 外键关系建立问题 二 添加表记录(一) 一对多添加记录(二) 多对多添加记录(三) 多对多关系常用的API 三 基于对象的跨表查询(一) 两种跨表查询方式及正、反向查询(二) 一对多查询(三) 一对一查询(四) 多对多查询 四 基于双下划线的跨表查询(一) 一对多查询(二) 多对多查询(三) 一对一查询(四) 进阶之连续跨表查询(五) 总结 五 聚合查询与分组查询(一) 聚合查询(二) 分组查询(三) 多表查询练习 六 F查询与Q查询(一) F查询(二) Q查询 七 其他补充(一) 安装模块相关补充(二) 前后端分离和混合开发

一 创建模型

(一) 模型创建

1) 图书表:book,作者表:author,作者详情表:authordetail,出版社表:publish,(第三张中间表)2) 作者跟作者详情:是一对一,关联字段写在哪一方都可以 3) 图书跟出版社:是一对多,【一对多关系一旦确立,关联字段写在多的一方】 4) 图书和作者:是多对多,多对多的关系需要建立第三张表(可以自动生成) 5) models.py中把关系建立出来 from django.db import models ### django: 1.11.1 2.0.7 # Create your models here. class Publish(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) addr = models.CharField(max_length=128) phone = models.CharField(max_length=64) email = models.EmailField() # admin元数据相关【只有建的表才生效】 class Meta: verbose_name = '出版社' verbose_name_plural = '出版社' # 定制admin中显示的数据【只有建的表才生效】 def __str__(self): return self.name """以下为Book表后添加的字段,添加后做一下数据库迁移""" # 阅读数 # reat_num=models.IntegerField(default=0) # 评论数 # commit_num=models.IntegerField(default=0) class Book(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) publish_date = models.DateTimeField(auto_now_add=True) # to='Publish' 跟Publish表做关联(ForeignKey,一对多) # to_field='id' 跟哪个字段做关联(字段必须是unique=True), 不写,默认跟主键做关联 # on_delete 表示约束类型,1.x版本默认CASCADE,2.X以上版本必须设置,有三个参数 # publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE) # 级联删除 # publish = models.ForeignKey(to='Publish', on_delete=models.SET_DEFAULT,default=0) # 关联字段删除,被关联字段不删除,设置为0 publish = models.ForeignKey(to='Publish', on_delete=models.SET_NULL, null=True) # 关联字段删除,被关联字段不删除,设置为空 # 自动创建出的第三张表,表示两个表的关联关系 # authors在数据库中不存在该字段,所以没有to_field # 默认情况:第三张表有id字段,当前Book表的id和Author表的id字段,不可以自定义添加字段 authors = models.ManyToManyField(to='Author') class Author(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.SmallIntegerField() # 一对一的本质是 ForeignKey+unique author_detail = models.OneToOneField(to='AuthorDetail', to_field='id', on_delete=models.CASCADE) # 可以使用ForeignKey+unique来写,但是不推荐这样写,标识性不强 # author_detail=models.ForeignKey(to='AuthorDetail',to_field='id',unique=True) class AuthorDetail(models.Model): id = models.AutoField(primary_key=True) gender = models.SmallIntegerField() addr = models.CharField(max_length=64) phone = models.BigIntegerField() 6) 同步到mysql数据库 -配置文件 -pymysql.install_as_mysqldb() -公司可能用的mysqlclient -两条命令 7) 2.x版本的django -外键字段必须加 参数:on_delete -1.x版本不需要,默认就是级联删除 -举例假设: 删除出版社,该出版社出版的所有图书也都删除,on_delete=models.CASCADE 删除出版社,该出版社出版的图书不删除,设置为空on_delete=models.SET_NULL,null=True 删除出版社,该出版社出版的图书不删除,设置为默认on_delete=models.SET_DEFAULT,default=0 # default必须是数字 # 注意: 1) 便于理解:一对一的本质是 ForeignKey+unique

(二) 外键关系建立问题

1) 关联字段与外键约束没有必然的联系(建关联字段是为了进行查询,建约束是为了不出现脏数据) 2) 默认情况,关联关系建好以后,外键约束就自然建立了 3) 实际工作中,外键约束一般不建(影响效率),都是人为约束(代码约束) -db_constraint=False 4) 表模型和数据库表的对应,不要直接修改表(这是可以的,但是不建议),要修改表模型,同步到表中

二 添加表记录

(一) 一对多添加记录

# 脚本文件的设置 import os if __name__ == '__main__': os.environ.setdefault('DJANGO_SETTINGS_MODULE', '项目名.settings') import django django.setup() from app01 import models # 基本数据: # 书 名: 西游记、 红楼梦、 诛仙、 Python从入门到入狱、 三体 # book_id: 1 2 3 4 5 # 作 者: 刘老牛、 小矮根、 萧鼎、 刘老牛、小矮根、 刘慈欣 # 出版社: 北京、 北京、 北京、 沙河、 三体 # 一对多添加记录(出版社和图书) # 先增加出版社,再增加图书,因为外键约束在图书侧 # 新增北京、沙河、三体出版社 publish_obj1 = models.Publish.objects.create(name='北京出版社',addr='北京',phone='010-66666666',email='bj@qq.com') publish_obj2 = models.Publish.objects.create(name='沙河出版社',addr='北京',phone='010-88888888',email='sh@qq.com') publish_obj3 = models.Publish.objects.create(name='三体出版社',addr='三体星',phone='010-77777777',email='st@qq.com') # 新增 西游记、红楼梦、诛仙、Python从入门到入狱、三体 # publish 与 publish_id : publish=publish_obj【可以等于上面插入数据时的对象】,也可以直接设置publish_id book_obj1 = models.Book.objects.create(name='西游记', price='21', publish_id=1) book_obj2 = models.Book(name='红楼梦', price='22.22', publish_id=1) book_obj2.save() book_obj3 = models.Book.objects.create(name='诛仙', price='66.66', publish_id=1) book_obj4 = models.Book.objects.create(name='Python从入门到入狱', price='0.5', publish_id=2) book_obj5 = models.Book.objects.create(name='三体', price='99.99', publish_id=3) book = models.Book.objects.get(name='红楼梦') # print('出版社对象', book.publish) # 出版社对象 Publish object (1) # print('出版社对象id', book.publish.id) # 出版社对象id 1 # print('出版社id', book.publish_id) # 出版社id 1 # 总结: 1 email可以不传email,本质就是varchar(admin中会判断) 2 新增图书: -publish=publish -publish_id=publish.id 3 写在表模型中的publish字段,到数据库中会变成publish_id(ForeignKey) 4 查到book对象以后 -book.publish 对象 -book.publish_id id号,数字

(二) 多对多添加记录

# 多对多,作者和书 # 给 Python从入门到入狱 增加作者刘老牛,小矮根; # 增加作者及目标id,刘老牛【1】、小矮根【2】、萧鼎【3】、刘慈欣【4】 # 由于一对一关联字段,需要先建立作者详情 author_detail_obj1 = models.AuthorDetail.objects.create(gender=0, addr='北京沙河', phone=15512345678) author_detail_obj2 = models.AuthorDetail.objects.create(gender=0, addr='北京沙河', phone=15587654321) author_detail_obj3 = models.AuthorDetail.objects.create(gender=0, addr='福建福州', phone=17767676767) author_detail_obj4 = models.AuthorDetail(gender=0, addr='山西娘子关', phone=18878787878) author_detail_obj4.save() # # 增加作者信息: author_list = {'刘老牛': [18, 1], '小矮根': [81, 2], '萧鼎': [33, 3], '刘慈欣': [32, 4]} for a_name, age_id in author_list.items(): models.Author.objects.create(name='%s' % a_name, age=age_id[0], author_detail_id=age_id[1]) # 查改操作: # 对数据和作者进行关联操作【增删改查】 book_obj1 = models.Book.objects.get(name='西游记') book_obj2 = models.Book.objects.get(name='红楼梦') book_obj3 = models.Book.objects.get(name='诛仙') book_obj4 = models.Book.objects.get(name='Python从入门到入狱') book_obj5 = models.Book.objects.get(name='三体') # add()【增加】; remove()【删除】; clear()【清空】; set()【先清空,再add,前提是不存在的作者,已存在的不增加】; book_obj1.authors.add(1) book_obj2.authors.add(2) book_obj3.authors.add(3) book_obj4.authors.add(1, 2) book_obj5.authors.add(4)

(三) 多对多关系常用的API

# add()【增加】; remove()【删除】; clear()【清空】; set()【先清空,再add,前提是不存在的作者,已存在的不增加】; #1) 给 Python从入门到入狱 重新设置作者 为 3,4 set([]),传值用列表 或者 元组 book_obj4.authors.set((3, 4)) #2) 给 Python从入门到入狱 删除作者 4 book_obj4.authors.remove(4) #3) 给 Python从入门到入狱 清空作者 book_obj4.authors.clear() #4) 给 Python从入门到入狱 增加作者 1 2 book_obj4.authors.add(1, 2)

三 基于对象的跨表查询

(一) 两种跨表查询方式及正、反向查询

#1) 跨表查询有两种方式 -基于对象的跨表查询:子查询 -基于双下划线的跨表查询:关联查询,连表查询 #2) 正、反向查询: # 个人理解,正反向取决于最终查数据时,是直接使用字段本身,还是使用(另一个)小写表_字段去取。 # 正向查询:book表内有publish字段 直接对象.字段名 # 反向查询:publish表内没有book字段,出版社对象.Book小写_set.all() #3) 总结: # 基于对象的跨表查询,先查对象,通过对象再去查另一个对象(正向:字段名,反向:表名小写【一对一】/表名小写_set.all()【一对多】)

(二) 一对多查询

# ——》》一对多【执行了两次查询】 # 查询主键为1的书籍的出版社所在的城市 book_obj = models.Book.objects.get(id=1) # 第一次查询 # # (0.000) SELECT `app01_book`.`id`, `app01_book`.`name`, `app01_book`.`price`, `app01_book`.`publish_date`, `app01_book`.`publish_id` FROM `app01_book` WHERE `app01_book`.`id` = 1; args=(1,) # book_obj = models.Book.objects.filter(id=1).first() publish = book_obj.publish # 内部又执行了第二次查询,根据publish_id查询publish # (0.000) SELECT `app01_publish`.`id`, `app01_publish`.`name`, `app01_publish`.`addr`, `app01_publish`.`phone`, `app01_publish`.`email` FROM `app01_publish` WHERE `app01_publish`.`id` = 1; args=(1,) print(publish.addr) addr = models.Book.objects.get(id=1).publish.addr print(addr) # # 北京出版社出版的所有书籍 publish = models.Publish.objects.get(name='北京出版社') # 第一次查询了出版社 books = publish.book_set.all() # 表名小写_set ,.all()后得到一个queryset对象 # 第二次,根据出版社id,查询所有书 print(books) # <QuerySet [<Book: Book object (1)>, <Book: Book object (2)>, <Book: Book object (3)>]>

(三) 一对一查询

# ——》》一对一 # 查询所有住址在 北京 的作者的姓名 # 反向查询:author_detail 没有author字段,author_detail.表名小写 # author_detail = models.AuthorDetail.objects.get(addr__contains='北京') # app01.models.MultipleObjectsReturned: get() returned more than one AuthorDetail -- it returned 2! author_detail = models.AuthorDetail.objects.filter(addr__contains='北京') # 反向查询 for k in author_detail: print(k.author.name) # 查询 小矮根 作者的地址 # 正向查询,正常.关联表名小写 .author_detail.addr author = models.Author.objects.get(name='小矮根') print(author.author_detail.addr) # 北京沙河

(四) 多对多查询

# ————————》》多对多关系查询 # Python从入门到入狱 所有作者的名字以及手机号 book = models.Book.objects.get(name='Python从入门到入狱') # 正向查询 book表内有 authors 字段,直接对象.字段名 authors = book.authors.all() for author in authors: print(author.name) print(author.author_detail.phone) # 反向查询 查询 小矮根 出过的所有书籍的名字 # author 表内没有 book 字段,对象.Book小写_set.all() author_smallegon = models.Author.objects.get(name='小矮根') books = author_smallegon.book_set.all() for book in books: print(book.name) # # 地址为 山西娘子关 的作者写的所有书 author_detail = models.AuthorDetail.objects.get(addr='山西娘子关') author = author_detail.author books = author.book_set.all() print(books[0].name) # # 地址为 山西娘子关 的作者写的所有书的出版社名字 author_detail = models.AuthorDetail.objects.get(addr='山西娘子关') author = author_detail.author books = author.book_set.all() for book in books: print(book.publish.name)

四 基于双下划线的跨表查询

(一) 一对多查询

# ————————》》基于双下划线的跨表查之 一对多 # 正向: 字段名 # 反向: 表名小写 # filter,values,values_list(写 __ 跨表) # 练习: 查询 北京出版社 出版过的所有书籍的名字与价格(一对多) res = models.Publish.objects.filter(name='北京出版社').values('book__name', 'book__price') print(res) # <QuerySet [{'book__name': '西游记', 'book__price': Decimal('21.00')}, {'book__name': '红楼梦', 'book__price': Decimal('22.22')}, {'book__name': '诛仙', 'book__price': Decimal('66.66')}]> res = models.Book.objects.filter(publish__name='北京出版社').values('name', 'price') print(res) # <QuerySet [{'name': '西游记', 'price': Decimal('21.00')}, {'name': '红楼梦', 'price': Decimal('22.22')}, {'name': '诛仙', 'price': Decimal('66.66')}]>

(二) 多对多查询

# ————————》》基于双下划线的跨表查之 多对多 # 练习: 查询 刘老牛 出过的所有书籍的名字,价格(多对多) # 正向查询 res = models.Book.objects.filter(authors__name='刘老牛').values('name', 'price') print(res) # <QuerySet [{'name': '西游记', 'price': Decimal('21.00')}, {'name': 'Python从入门到入狱', 'price': Decimal('0.50')}]> # 反向查询 res = models.Author.objects.filter(name='刘老牛').values('book__name', 'book__price') print(res)

(三) 一对一查询

# 查询 萧鼎 的手机号 res = models.Author.objects.filter(name='萧鼎').values('author_detail__phone') print(res) res = models.AuthorDetail.objects.filter(author__name='萧鼎').values('phone') print(res)

(四) 进阶之连续跨表查询

# ————————》》连续跨表 # 查询 北京出版社 出版过的所有书籍的名字以及作者的姓名 res = models.Publish.objects.filter(name='北京出版社').values('book__name', 'book__authors__name') print(res) res = models.Author.objects.filter(book__publish__name='北京出版社').values('book__name', 'name') print(res) res = models.Book.objects.filter(publish__name='北京出版社').values('name', 'authors__name') print(res) # 手机号以155开头的作者 出版过的所有 书籍名称 以及 出版社名称 res = models.AuthorDetail.objects.filter(phone__startswith='155').values('author__book__name', 'author__book__publish__name') print(res) # (0.000) SELECT `app01_book`.`name`, `app01_publish`.`name` FROM `app01_author` INNER JOIN `app01_authordetail` ON (`app01_author`.`author_detail_id` = `app01_authordetail`.`id`) LEFT OUTER JOIN `app01_book_authors` ON (`app01_author`.`id` = `app01_book_authors`.`author_id`) LEFT OUTER JOIN `app01_book` ON (`app01_book_authors`.`book_id` = `app01_book`.`id`) LEFT OUTER JOIN `app01_publish` ON (`app01_book`.`publish_id` = `app01_publish`.`id`) WHERE `app01_authordetail`.`phone` LIKE BINARY '155%' LIMIT 21; res = models.Author.objects.filter(author_detail__phone__startswith='155').values('book__name', 'book__publish__name') print(res) # <QuerySet [{'book__name': '西游记', 'book__publish__name': '北京出版社'}, {'book__name': 'Python从入门到入狱', 'book__publish__name': '沙河出版社'}, {'book__name': '红楼梦', 'book__publish__name': '北京出版社'}, {'book__name': 'Python从入门到入狱', 'book__publish__name': '沙河出版社'}]>

(五) 总结

# 基于双下划线的跨表查询(连表查询) -filter,values,vlues_list中写 __ 连表 - 正向:字段名 - 反向:表名小写

五 聚合查询与分组查询

(一) 聚合查询

# aggregate(*args, **kwargs) aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的【字典】。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它。 # #---->>>> 1 聚合查询(聚合函数:最大,最小,和,平均,总个数) from django.db.models import Avg, Max, Min, Count, Sum # 1 计算所有图书的平均价格 # aggregate结束,已经不是queryset对象了 book = models.Book.objects.all().aggregate(Avg('price')) # # 【起别名】-->> avg=Avg('price') # book = models.Book.objects.all().aggregate(avg=Avg('price')) print(book) # {'price__avg': 42.074} # 2 计算总图书数 book = models.Book.objects.all().aggregate(count=Count('id')) print(book) # {'count': 5} # 3 计算最低价格的图书 book = models.Book.objects.all().aggregate(min=Min('price')) print(book) # {'min': Decimal('0.50')} # 4 计算最大价格图书 book = models.Book.objects.all().aggregate(max=Max('price')) print(book) # {'max': Decimal('99.99')}

(二) 分组查询

#1) annotate() 内写聚合函数为调用的QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数)。 ### 以下的【在前与在后】,均以annotate()位置为参照!!!! #2) values在前表示group by的字段 #3) values在后表示取某几个字段【只可以取分组字段和[聚合函数修饰后]的自他表内字段!】 #4) filter在前表示where #5) filter在后表示having # 总结 :跨表分组查询本质就是将关联表join成一张表,再按单表的思路进行分组查询。  # #---->>>> 2 分组查询--》单表 ''' id name price publish_id 1 西游记 21.00 1 2 红楼梦 22.22 1 3 诛仙 66.66 1 4 Python从入门到入狱 0.50 2 5 三体 99.99 3 ''' from django.db.models import Avg, Max, Min, Count, Sum # 示例一:查询每一个出版社id,以及出书平均价格 # SELECT publish_id, AVG(price) FROM app01_book GROUP BY publish_id; ret = models.Book.objects.values('publish_id').annotate(avg=Avg('price')).values('publish_id', 'avg') print(ret) # <QuerySet [{'publish_id': 1, 'avg': 36.626667}, {'publish_id': 2, 'avg': 0.5}, {'publish_id': 3, 'avg': 99.99}]> # 查询出版社id大于1的出版社id,以及出书平均价格 # SELECT publish_id, AVG(price) FROM app01_book WHERE publish_id>1 GROUP BY publish_id; ret = models.Book.objects.filter(publish_id__gt=1).values('publish_id').annotate(avg=Avg('price')).values('publish_id', 'avg') print(ret) # <QuerySet [{'publish_id': 2, 'avg': 0.5}, {'publish_id': 3, 'avg': 99.99}]> # 查询出版社id大于1的出版社id,以及出书平均价格大于30的 # SELECT publish_id, AVG(price) AS aaa FROM app01_book WHERE publish_id>1 GROUP BY publish_id HAVING aaa>30; ret = models.Book.objects.filter(publish_id__gt=1).values('publish_id').annotate(avg=Avg('price')).filter(avg__gt=30).values('publish_id', 'avg') print(ret) # <QuerySet [{'publish_id': 3, 'avg': 99.99}]>

(三) 多表查询练习

# #---->>>> 2 分组查询--》多表 # 1) 查询每一个出版社出版的书籍个数 # pk 代指主键 # select Count('id') from app01.publish inner join app01.book on ret = models.Book.objects.get(pk=1) print(ret) # 西游记 ### 方式一: ret = models.Publish.objects.values('pk').annotate(count=Count('book__id')).values('name', 'count') print(ret) # <QuerySet [{'name': '北京出版社', 'count': 3}, {'name': '沙河出版社', 'count': 1}, {'name': '三体出版社', 'count': 1}]> ### 另一种方式实现 ret = models.Book.objects.values('publish_id').annotate(count=Count('publish_id')).values('publish__name', 'count') print(ret) # <QuerySet [{'publish__name': '北京出版社', 'count': 3}, {'publish__name': '沙河出版社', 'count': 1}, {'publish__name': '三体出版社', 'count': 1}]> # 2) 查询每个作者的名字,以及出版过书籍的最高价格(建议使用分组的表作为基表) # 如果不用分组的表作为基表,数据不完整可能会出现问题 ret = models.Author.objects.values('pk').annotate(max=Max('book__price')).values('name', 'max') print(ret) # <QuerySet [{'name': '刘老牛', 'max': Decimal('21.00')}, {'name': '小矮根', 'max': Decimal('22.22')}, {'name': '萧鼎', 'max': Decimal('66.66')}, {'name': '刘慈欣', 'max': Decimal('99.99')}]> #---->>>> group_by 不写的话,默认使用基表的【主键】字段进行分组(不同版本可能使用的默认字段不同) ret = models.Author.objects.annotate(max=Max('book__price')).values('name', 'max') print(ret) ret = models.Book.objects.values('authors__id').annotate(max=Max('price')).values('authors__name', 'max') print(ret) # <QuerySet [{'authors__name': '刘老牛', 'max': Decimal('21.00')}, {'authors__name': '小矮根', 'max': Decimal('22.22')}, {'authors__name': '萧鼎', 'max': Decimal('66.66')}, {'authors__name': '刘慈欣', 'max': Decimal('99.99')}]> # 3) 查询每一个书籍的名称,以及对应的作者个数 ret = models.Book.objects.values('pk').annotate(count=Count('authors__id')).values('name', 'count') print(ret) # <QuerySet [{'name': '西游记', 'count': 1}, {'name': '红楼梦', 'count': 1}, {'name': '诛仙', 'count': 1}, {'name': 'Python从入门到入狱', 'count': 2}, {'name': '三体', 'count': 1}]> ret = models.Author.objects.values('book__id').annotate(count=Count('id')).values('book__name', 'count') print(ret) # <QuerySet [{'book__name': '西游记', 'count': 1}, {'book__name': '红楼梦', 'count': 1}, {'book__name': '诛仙', 'count': 1}, {'book__name': 'Python从入门到入狱', 'count': 2}, {'book__name': '三体', 'count': 1}]> # 4) 统计不止一个作者的图书 ret = models.Book.objects.values('pk').annotate(count=Count('authors__id')).filter(count__gt=1).values('name', 'count') print(ret) # <QuerySet [{'name': 'Python从入门到入狱', 'count': 2}]> ret = models.Author.objects.values('book__id').annotate(count=Count('id')).filter(count__gt=1).values('book__name', 'count') print(ret) # <QuerySet [{'book__name': 'Python从入门到入狱', 'count': 2}]> # 5) 统计价格数大于10元,作者的图书 ret = models.Book.objects.filter(price__gt=10).values('pk').annotate(count=Count('authors__id')).values('name', 'count') print(ret) # <QuerySet [{'name': '西游记', 'count': 1}, {'name': '红楼梦', 'count': 1}, {'name': '诛仙', 'count': 1}, {'name': '三体', 'count': 1}]> # 6) 统计价格数大于10元,作者个数大于1的图书 ret = models.Book.objects.filter(price__gt=10).values('pk').annotate(count=Count('authors__id')).filter(count__gt=1).values('name', 'count') print(ret) # <QuerySet []>

六 F查询与Q查询

(一) F查询

# #---->>>> F查询:取出数据库的某个字段的值 from django.db.models import F # # 1) 把read_num都加1 ret = models.Book.objects.all().update(read_num=F('read_num')+1) print(ret) # 5 # # 2) 查询评论数大于阅读数的书籍 ret = models.Book.objects.all().filter(commit_num__gt=F('read_num')) for i in ret: print(i.name, end='<-->') # 诛仙<-->Python从入门到入狱<--> # # 3) 查询评论数大于阅读数2倍的书籍 ret = models.Book.objects.all().filter(commit_num__gt=F('read_num')*2) print(ret) # <QuerySet [<Book: Python从入门到入狱>]>

(二) Q查询

# #---->>>> Q查询:制造 与或非的条件 【Q还可以嵌套】 from django.db.models import Q # # 1) 查询名字叫 红楼梦 或者价格大于 90 的书 ret = models.Book.objects.filter(Q(name='红楼梦') | Q(price__gt=90)) print(ret) # <QuerySet [<Book: 红楼梦>, <Book: 三体>]> # # 2) 查询名字叫 红楼梦 或者价格大于 90 的书 ret = models.Book.objects.filter(Q(name='红楼梦') & Q(price__gt=90)) print(ret) # <QuerySet []> # # 3) 查询名字不为 红楼梦 的书 ret = models.Book.objects.filter(~Q(name='红楼梦')) print(ret) # <QuerySet [<Book: 西游记>, <Book: 诛仙>, <Book: Python从入门到入狱>, <Book: 三体>]> # Q 可以嵌套使用 # # 4) Q的嵌套 ret = models.Book.objects.filter((Q(name='红楼梦') & Q(price__gt=90)) | Q(id__gt=3)) print(ret) # <QuerySet [<Book: Python从入门到入狱>, <Book: 三体>]>

七 其他补充

(一) 安装模块相关补充

pip3 install django # 本质是去https://pypi.python.org/simple,搜这个模块,会根据你的平台下载在一个安装包(windows平台是whl),下载完,再安装 # pip安装失败的情况 # 我们可以绕过它,有了whl文件以后,自己装 # https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv pip3 install django.whl # 官方库没有上传到pypi,官方也不给制作whl文件 #如何安装 包 (setup.py) 到达安装目录,setup.py所在的目录 python setup.py build python setup.py install # 配置清华源,豆瓣源,本质是 豆瓣源会把pypi,包拉到自己的服务器上,以后你再下,去它的服务器上下,所以速度快 # 你自己写的包,如何上传到pypi上给别人使用?

(二) 前后端分离和混合开发

1) 模板语言:每个语言的web框架都会有模板语言,django---》dtl 2) 模板语言的渲染,是在后端完成的 3) 用php写前端(html,css,js)(是错误说法) 4) 前后端分离:前后端交互,统一全用json格式 5) 前端只专注于写前端(vue,react:前端工程化),后端只专注于写后端(提供接口,交互json格式数据)
最新回复(0)