zoukankan      html  css  js  c++  java
  • 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")
  • 相关阅读:
    select、poll和epoll
    Linux 常用命令之文件和目录
    SmartPlant Review 帮助文档机翻做培训手册
    SmartPlant Foundation 基础教程 3.4 菜单栏
    SmartPlant Foundation 基础教程 3.3 标题栏
    SmartPlant Foundation 基础教程 3.2 界面布局
    SmartPlant Foundation 基础教程 3.1 DTC登陆界面
    SmartPlant Foundation 基础教程 1.4 SPF架构
    SmartPlant Foundation 基础教程 1.3 SPF其他功能
    SmartPlant Foundation 基础教程 1.2 SPF集成设计功能
  • 原文地址:https://www.cnblogs.com/liuyinzhou/p/8502744.html
Copyright © 2011-2022 走看看