• ORM的查询操作


    查询的分类

     1 class Author(models.Model):
     2     name = models.CharField(max_length=32)
     3     age = models.IntegerField()
     4 
     5     # 与AuthorDetail建立一对一的关系
     6         ad = models.OneToOneField(to="AuthorDetail")
     7 
     8 class AuthorDetail(models.Model):
     9     birthday = models.DateField()
    10     telephone = models.BigIntegerField()
    11     addr = models.CharField(max_length=64)
    12 
    13 class Publish(models.Model):
    14     name = models.CharField(max_length=32)
    15     city = models.CharField(max_length=32)
    16     email = models.EmailField()
    17 
    18 
    19 class Book(models.Model):
    20 
    21     title = models.CharField(max_length=32)
    22     publishDate = models.DateField()
    23     price = models.DecimalField(max_digits=5, decimal_places=2)
    24     keepNum = models.IntegerField()
    25     commentNum = models.IntegerField()
    26 
    27     # 与Publish建立一对多的关系,外键字段建立在多的一方
    28     publish = models.ForeignKey(to="Publish", to_field="nid")
    29 
    30     # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任
    31         #意一个,自动创建第三张表
    32     authors = models.ManyToManyField(to='Author')
    33 
    34 
    35         三个关联字段:   
    36 
    37             # 与AuthorDetail建立一对一的关系
    38         ad = models.OneToOneField(to="AuthorDetail")
    39             
    40             # 与Publish建立一对多的关系,外键字段建立在多的一方
    41         publish = models.ForeignKey(to="Publish", to_field="nid")
    42 
    43         # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的                      任意一个,自动创建第三张表
    44        authors = models.ManyToManyField(to='Author')
    表关系

      基于对象的查询(子查询)

        查询思想:

          首先得到一个对象,通过此对象进行正向查询或者反向查询。

        使用条件:

          使用的前提必须是一个对象,在一对多与多对多的环境下才能使用对象.表名小写_set().all();在一对一的环境下,使用对象.表明小写

        一对一

          正向按照字段:对象.外键字段.字段

          表一---------------------------->表二

          表一<----------------------------表二

          反向按照表名:对象.表名小写.字段

    示例:

    1 #查询作者阿童木的邮箱地址(正向)
    2 auth_obj = Author.objects.filter(name="阿童木").first()
    3 print(auth_obj.detail.email)
    4 
    5 #查询邮箱以“1”开头的坐着的姓名(反向)
    6 detail_obj = Author_detail.objects.filter(email__startswith="1").first()
    7 print(detail_obj.author.name)

    注意:

      在一对一的关系中,不管是正向还是反向查询得到的只能是一个结果,因此不需要加"_"。

      但是在一对多或多对多的关系中,一 的一方找多的一方,正向使用"对象.字段"的格式进入另一张表,反向使用“对象.表名小写_set”进入另一张表。

         一对多 

           正向按照字段:对象.外键字段.字段

          表一---------------------------->表二

          表一<----------------------------表二

           反向按照表名小写:对象.表名小写_set.字段

    示例:

    1 #查询“葵花宝典”这本书的出版社的名称(正向)
    2 book_obj = Book.objects.filter(title="葵花宝典").first()
    3 book_obj.publisher.name
    4 
    5 #查询“北京邮电出版社”出版的所有书籍的名称(反向)
    6 publish_obj = Publish.objects.filter(name="北京邮电出版社").first()
    7 publish_obj.book_set.values("title")

        多对多 

              正向按照字段

          表一---------------------------->表二

          表一<----------------------------表二

              反向按照表名小写_set()

    示例:

    1 #查询“葵花宝典”这本书的所有作者的姓名和年龄(正向)
    2 book_obj = Book.objects.filter(title="葵花宝典").first()
    3 book_obj.author.all().values("name","age")
    4 
    5 #查询“阿童木”所出版的所有书的名称和价格(反向)
    6 author_obj  = Author.objects.filter(name="阿童木").first()
    7 author_obj.book_set.all().values("title","price")

      基于Queryset的查询(连表查询)

        注意:

          在使用基于QuerySet的双下划线进行查询的时候,不管是一对一,一对多还是多对多,都使用表名小写__字段。

          一对一

            正向按照字段:Queryset.values("外键字段__字段")

            表一---------------------------->表二

            表一<----------------------------表二

            反向按照表名:Queryset.values("表名小写__字段")

    示例:

    1 #查询作者为“阿童木”的邮箱地址(正向)
    2 Author.objects.filter(name="阿童木").values("detail__email")
    3 
    4 #查询邮箱以“1”开头的作者姓名
    5 Author_detail.objects.filter(email__startswith="1").values("author__name")

          一对多

            正向按照字段:对象.外键字段.字段

            表一---------------------------->表二

            表一<----------------------------表二

            反向按照表名:Queryset.values("表名小写__字段")

    示例:

    1 #查询"葵花宝典"这本书的出版社的名称和所在城市(正向)
    2 Book.objects.filter(title="葵花宝典").values("publisher__name","publisher__city")
    3 
    4 #查询“北京邮电出版社”所出版的所有书籍的名称和价格(反向)
    5 Publish.objects.filter(name="北京邮电出社").values("book__title","book__price")

          多对多 

            正向按照字段:对象.外键字段.字段

            表一---------------------------->表二

            表一<----------------------------表二

            反向按照表名:Queryset.values("表名小写__字段")

    示例:

    1 #查询“葵花宝典”这本书的作者名称和email(正向,两次跨表)
    2 Book.objects.filter(title="葵花宝典").values("author__name","author__detail__email")
    3 
    4 #查询阿童木的出版的所有书籍的名称和价格(反向)
    5 Author.objects.filter(name="阿童木").values("book__title","book__price")

    聚合

    1 from django.db.models import Avg,Sum,Count,Max,Min
    2 # 1、查询所有图书的平均价格
    3 print(models.Book.objects.all().aggregate(Avg("price")))

    aggregate()QuerySet 的一个终止子句(也就是返回的不再是一个QuerySet集合的时候),意思是说,它返回一个包含一些键值对的字典键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它。

    1 # 1、查询所有图书的平均价格
    2 print(models.Book.objects.all().aggregate(avgprice = Avg("price")))

    如果你希望生成不止一个聚合,你可以向aggregate()子句中添加另一个参数。所以,如果你也想知道所有图书价格的最大值和最小值,可以这样查询:

    1 print(models.Book.objects.all().aggregate(Avg("price"),Max("price"),Min("price")))
    2 #打印的结果是:  {'price__avg': 174.33333333333334, 'price__max': Decimal('366.00'), 'price__min': Decimal('12.00')}

    分组

    1 #查询每一个出版社出版过的书籍数量和出版社名称
    2 Publish.objects.all().annotate(c=Count("book")).values("name","c")
  • 相关阅读:
    数组删除元素注意事项
    点击下拉菜单以外的区域,关闭弹窗
    webpack学习笔记(六)优化
    webpack学习笔记(五)
    webpack学习笔记(四)
    webpack学习笔记(三)
    webpack学习笔记(二)
    es6 笔记
    vue学习笔记——组件的优化
    vue学习笔记——路由
  • 原文地址:https://www.cnblogs.com/liuyinzhou/p/8502744.html
Copyright © 2020-2023  润新知