from django.db import models # Create your models here. class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday = models.DateField() telephone = models.BigIntegerField() addr = models.CharField(max_length=64) 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") 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.DateField() price = models.DecimalField(max_digits=5, decimal_places=2) keepNum = models.IntegerField() commentNum = models.IntegerField() # 与Publish建立一对多的关系,外键字段建立在多的一方 publish = models.ForeignKey(to="Publish", to_field="nid",) # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors = models.ManyToManyField(to='Author')
基于对象查询跨表查询(利用子查询) #子查询:将上次的查询结果作为本次的查询条件使用
一对一
正向查询按字段
查询alex的手机号 Author.objects.filter("name"="alex").first() obj.authorDetail.telephone
反向查询按小写表名
住在烟台的作者的名字 obj_list=AuthorDetail.objects.filter(addr="烟台") for obj in obj_list: print(obj.author.name)
一对多
正向查询按字段
查询id为2的书籍对应出版社的邮箱 obj=Book.objects.filter(nid=2).first() #filter()得到的是queryset,想要得到对象需要加[0]或者first() obj.publish.email
SQL语句:
select email from Publish where nid=(select publish_id from Book where nid=2)
反向查询按小写表名_set
橘子出版社出版过的所有的书籍的名字 先找到橘子出版社的对象 obj=Publish.objects.filter(name="橘子出版社").first() obj.book_set.all().values("title") #values表示中填写要显示的字段名
多对多
正向查询按字段
查询时间简史所有作者的名字
Book.objects.filter(title="时间简史").first() obj.authors.all().values("name")
反向查询按小写表名_set
查询alex出版的书籍个数 找到alex对象 obj=Author.objects.filter("name"="alex").first() obj.book_set.all().count()
基于queryset和__的跨表查询(join查询)
正向查询安字段
查询id为2的书籍对应出版社的邮箱 Book.objects.filter(nid=2).values("publish__email")
反向查询安表名
橘子出版社出版过的所有的书籍的名字 Publish.objects.filter("name"="橘子").values("book__title")
查询alex出版的书籍个数
Author.objects.filter("name"="alex").values("book__title").count()
分组查询
跨表分组查询
每一个出版社的名字以及对应出版书籍个数 #annotate前查询什么字段就按什么字段分组 Publish.objects.all().annotate(c=Count("book")).values("name",c) #得到的是每个出版社的对象 #annotate 内创建新的字段
查询每一个作者的名字以及对应书籍的平均价格
Author.objects.all().annotate(avg=Avg("price")).values("name",avg)
查询每一本书 的名字以及作者的个数
Book.objects.all().annotate(c=Count("authors")).values("title","c")
单表分组查询
查询每本书的个数
Book.objects.values("title").annotate(c=Count("*")).values("c") #单表分组查询以什么字段分组就在annotate前的values写什么字段