一对多查询( 修改表结构需要从新运行命令)
分析1对多外键放在多的一方
**建立外键
class Book(models.Model):
name = models.CharField(max_length=10)
price = models.IntegerField()
publish = models.ForeignKey('Piblish') # 建立外键
class Publish(models.Model):
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
默认django给外键自动添加 _id 表示外键 publish_id
子表先创建外键绑定 否则报错子表键不存在
主表添加外键字段:
Book.objects.create(name='q',price=22,publish_id=2)子表对象添加到主表中
publish_obj = Publish.objects.filter(name='w')[0]Book.objects.create(name='q',price=22,publish_id=publish_obj)
转换成对象关联查询:
book_obj = Book.objects.get(name='q') # 通过书查找出版社print(book_obj.publish.name) # 通过publish
查询w出过的所有书籍的名字和价格
方式一:
publish_obj = Publish.objects.filter(name='w')[0]
ret = Book.objects.filter(publish=publish_obj).values('name','price')
*****使用查询记录(filter values 双下划线__)
根据父表找子表内容 publish外键对象 sql就是join连接Book.objects.filter(publish__name='人民出版').values('name','price')
反向关联book是类名字 没有外键
Publish.objects.filter(book__name='python').values('name')
对结果进行关联筛选 values
Book.objects.filter(name='python').values("publish__name")
例:在北京出版社 出版的书
正向
Publish.objects.filter(city='北京').values('publish__name')
反向
Book.objects.first(publish__city='北京').values('name')
表操作:多对多( 修改表结构需要从新运行命令)
第三张表建立关系1表 class Book(models.Model):
name=models.CharField(max_length=32)
price=models.CharField(max_length=32)
authors=models.ManyToManyField('Author') # 建立多表
def __str__(self):
return self.name
2表 class Author(models.Model):
name=models.CharField(max_length=32)
age=models.IntegerField(default=20)
def __str__(self):
return self.name
系统看到 ManyToMany 自动创建第三张表
Book.authors 拿到的是 QuerySet集合
正向查询:
Book.authors.get(id=1).authors.all()
反向查询:
Author.objects.get(id=2).book_set.all()
book_obj = Book.objects.get(id=2)
书籍对象它的所有关联作者: obj = book_obj.authors.all()
绑定多对多关系: obj.add(*QuerySet)
obj.remove(*QuerySet)
通过双下划线查找
Book.objects.filter(author__name='a').values('name','price')重点: 通过 filter values 双下划线 进行多对多的关联查询(形式和一对多)
外键查询时用的都是外键字段 authors 加双下划线 进行过滤查询
和第三张表建立关系:
插入表记录:book_obj = Book.objects.get(id=2) 一本书
author_objs = Author.objects.all() 拿到作者集合 Author.objects.get(id=1) 添加一本
book_obj.authors.add(*author_objs) 添加集合
重复的就不会绑定
book_obj.authors.remove(*alert_objs) # 删除所有绑定
book_obj.authors.remove(2) # 删除绑定书作者的id
了解:
如果想向第三张表插入值得方式解除关系: 可以自己创建第三张表:class Book_Author(models.Model):
book = models.ForeignKey('Book'),
author = models.ForeignKey('Author')
插入表记录:
Book_Author.objects.create(book_id=2,author_id=3)通过对象查找
obj = Book.objects.get(id=2)obj.book_author_set.all()[0].author # 拿到作者信息
查询:
通过双下划线Book.objects.filter(book_author__author__name='a').values('name','price')
聚合函数
Book.objects.all().aggregate(AVG('price')) # 求出所有书价格的平均值Book.objects.filter(authors__name='q').aggregate(Sum('price')) # 求出名字为q的所有书籍价钱
Book.objects.filter(authors__name='q').aggregate(count('name')) # 个数
max min
分组
Book.objects.values('authors__name').annotate(Sum('price'))# 分组后使用聚合函数
Book.objects.values('name').annotate(Min('book_price'))