表关系:
from django.db import models # Create your models here. class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() # 与AuthorDetail建立一对一的关系 authorDetail = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE) class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday = models.DateField() telephone = models.BigIntegerField() addr = models.CharField(max_length=64) class Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.EmailField() class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_length=32) publishDate = models.DateTimeField() price = models.DecimalField(max_digits=5, decimal_places=2) # 与Publish建立一对多的关系,外键字段建立在多的一方 publish = models.ForeignKey(to="Publish", to_field="nid", on_delete=models.CASCADE) # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors = models.ManyToManyField(to='Author', )
练习:
一、基于对象查询(子查询)
1、正向查询:出版社与书籍属于一对多关系,关系字段在书籍表中,通过书籍表找出版社属于正向查询
# 查询书籍名称是python的出版社名称,对象点字段的形式查询即可(obj.publish.name) ret = models.Book.objects.filter(title='python').first().publish.name print(ret)
2、反向查询: 出版社与书籍属于一对多关系,关系字段在书籍表中,通过出版社表找书籍表属于反向查询
# 查询出版社id为1的出版社,出版过哪些书籍。表名加__set ret = models.Publish.objects.filter(nid=1).first().book_set.values('title') print(ret)
二、基于QuerySet和"__"查询(连表查询)
1、正向查询:出版社与书籍属于一对多关系,关系字段在书籍表中,通过书籍表找出版社属于正向查询
# 查询python这本书籍的出版社的邮箱:values('关联字段__字段') ret = models.Book.objects.filter(title='python').values('publish__email') print(ret)
ret = ret = models.Publish.objects.filter(book__title='python').values('email')
print(ret)
2、反向查询:同理,通过出版社表找书籍表属于反向查询
# 查询永丰出版社出版过的书籍名称:values('表名__字段') # 方法一: ret = models.Publish.objects.filter(name='永丰出版社').values('book__title') print(ret) # 方法二 ret = models.Book.objects.filter(publish__name='永丰出版社').values('title') print(ret)
三、聚合查询
aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典,而不是QuerySet和一个具体的对象
from django.db.models import Count, Avg, Sum, Max, Min # 查询所有书籍的价格总和 ret = models.Book.objects.aggregate(Sum('price')) print(ret)
四、分组查询:annotate前面是什么,就按照什么分组
# 查询永丰出版社的所有书籍的平均价格 ret = models.Publish.objects.values('name').annotate(avg=Avg('book__price')).values('name', 'avg').filter(name='永丰出版社') print(ret)
ORM语句与SQL语句对照:
gt大于、lt小于、order_by排序
# 查询书籍平均价格低于100的出版社:filter('字段名__lt') ret = models.Publish.objects.values('name').annotate(avg=Avg('book__price')).values('name', 'avg').filter(avg__lt=100) print(ret)
# 按照书籍平均价格对出版社进行排序 ret = models.Publish.objects.values('name').annotate(avg=Avg('book__price')).values('name', 'avg').order_by('avg') print(ret)