• Django聚合分组查询、常用字段


    首先回顾sql中聚合和分组的概念:

    如果没有分组,会把整张表作为一个大组,查询字段必须是聚合结果;如果有分组,分组之后,必须要使用聚合的结果作为having的条件。

    聚合查询

    聚合:aggregate(*args, **kwargs)

    规则:

    1.可以同时对多个字段进行聚合处理;

    2.是QuerySet对象方法;

    3.方法返回值为字典类型

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

    # 求书的平均价格
    from django.db.models import Avg, Sum, Max, Min, Count
    res = Book.objects.all().aggregate(Avg('price'))
    print(res)
    
    {'price__avg': 56.29}
    from django.db.models import Avg, Sum, Max, Min, Count
    res = Book.objects.all().aggregate(avg_price=Avg('price'))  # 给聚合结果字段起别名
    print(res)
    
    {'avg_price': 56.29}

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

    from django.db.models import Avg, Sum, Max, Min, Count
    res = Book.objects.all().aggregate(Max('price'), Min('price'))
    print(res)
    
    {'price__max': Decimal('88.88'), 'price__min': Decimal('33.33')}

    分组查询

    分组:annotate()

    语法:values('分组字段').annotate(别名=聚合函数('字段')).filter(聚合字段别名条件).values('取分组字段','取聚合字段别名')

    规则:

    1.values(...).annotate(...)为分组组合,values控制分组字段,annotate控制聚合字段
    2.values可按多个字段分组values('分组字段1', ..., '分组字段n'),??如果省略代表按操作表的主键分组
    3.可以同时对多个字段进行聚合处理annotate(别名1=聚合函数1('字段1'), ..., 别名n=聚合函数n('字段n'))
    4.分组后的的filter代表having判断,只对聚合字段进行条件判断,可以省略(对非聚合字段或分组字段进行条件判断代表where判断)
    5.取字段值values(...)省略默认取所有分组字段与聚合字段,也可以自主取个别分组字段及聚合字段(取字段的values中出现了非分组或非聚合字段,该字段自动成为分组字段)

    from django.db.models import Avg, Sum, Max, Min, Count
    # 案例:每个出版社出版的最贵的书的价格高于50元的出版社名与最高价格
    res = Book.objects.values('publish__name')
        .annotate(price=Max('price'))
        .filter(price__gt=50)
        .values('publish__name', 'price')
    print(res)

    方式二:

    # res = Publish.objects.values('name')
    # .annotate(high_price=Max('book__price'))
    # .filter(high_price__gt=50)
    # .values('name', 'high_price')
    # print(res)

    常用共有字段属性

    #1.null:默认为False,True表示字段可以为null
    #2.blank:默认为False,True表示字段可以为空
    #3.choices:可选的,限制了该选项的字段值必须是choice中的一个
    
    # choices是元组套元组的形式
    sex = models.SmallIntegerField(choices=((0, ''),(1, '')))
    # 如果想获得key对应的value,可以通过obj.get_sex(字段名)_display()的方式进行获取
    
    #4.db_column:自定义字段名
    #5.db_index:如果值为True,则设置索引
    #6.default:字段默认值
    #7.editable:默认为True,若为False,则不会在/admin/界面显示
    #8.primary_key:若设置为True,则表示将该字段设置为主键,一般情况下django默认会设置一个自增的id主键
    #9.unique:若设置为True,该字段值不可重复

    常用字段

    #1. AutoField():默认自增主键(primary_key=True),django会默认建立id字段主键
    #2. BooleanField():布尔字段,对应数据库tinyint类型
    #3. CharField():字符类型
        -- 字段属性max_length=64,数据长度,必须明确
    #4. DateField():年月日时间类型
        -- 字段属性auto_now=True,数据被更新就会更新时间
        -- 字段属性auto_now_add=True,数据第一次参数时产生
    #5. DateTimeField():年月日小时分钟秒时间类型
        -- 字段属性auto_now=True,数据被更新就会更新时间
        -- 字段属性auto_now_add=True,数据第一次参数时产生
    #6. DecimalField():混合精度的小数类型
        -- 字段属性max_digits=3,限定数字的最大位数(包含小数位)
        -- 字段属性decimal_places=2,限制小数的最大位数
    #7. IntegerField():整型

    不常用字段

    #1. BigAutoField():大整型自增
    #2. BigIntegerField():长整型
    #3. EmailField():邮箱字段,拥有/admin/验证
    #4. FloatField():浮点型小数
    #5. SmallIntegerField():小整型
    #6. TextField():大文本类型
    #7. FileField():文件字段

    关系字段

    #1.ForeignKey():外键字段
        --字段属性to关联模型类
        --字段属性to_field关联字段,省略默认关联主键
        --字段属性on_delete(外键关联数据被删除时的操作),它的值有:
            --models.CASCADE 级联删除
            --models.PROTECT 抛出异常
            --models.SET_NULL 设置空值
            --models.SET_DEFAULT 设置默认值
            --models.SET(value)自定义值
        --字段属性related_name自定义反向查询的字段名
        --字段属性db_constraint=False取消关联关系,但还可以使用连表查询,是否在数据库中创建外键约束,默认为True。
    通常写法:models.ForeignKey(to='关联的类名',null=True,on_delete=models.SET_NULL,db_constraint=False,related_name='本类名小写')
    注:
    1.null=True保证在关联数据删除时,字段的值可以为空
    2.
    on_delete=models.SET_NULL在关联数据删除时,将字段的值设置为空值
    3.db_constraint=False取消关联关系,但还可以使用连表查询
    #2.OneToOneField():一对一外键字段 -- 字段同外键 #3.ManyToManyField():多对多关系字段 -- 字段属性to关联模型类 -- 字段属性through关联关系表 -- 字段属性through_fields关联关系表中(本身类名小写字段, 关联表类名小写字段)

    1.断开外键关联的ForeignKey使用

    # 1、不使用ForeignKey方式断开关联,不再支持Django ORM连表查询语法
    class Publish(models.Model):
        name = models.CharField(max_length=20)
    class Book(models.Model):
        name = models.CharField(max_length=20)
        # 字段需要写_id来表示相关表的字段信息
        publish_id = models.IntegerField()
    
    # *****
    # 2、使用ForeignKey方式用db_constraint=False字段属性断开关联,依然支持Django ORM连表查询语法,建议使用
    class Publish(models.Model):
        name = models.CharField(max_length=20)
    class Book(models.Model):
        name = models.CharField(max_length=20)
        # 字段不需要写_id来表示相关表的字段信息,ORM会自动添加
        publish = models.ForeignKey(to='Publish', null=True, on_delete=models.SET_NULL, db_constraint=False)

    2.断开关联的多对多自动创建关系表

    # *****
    # 使用ManyToManyField方式用db_constraint=False字段属性断开关联,依然支持Django ORM连表查询语法,建议使用
    class MyBook(models.Model):
        name = models.CharField(max_length=20)
        my_author = models.ManyToManyField(to='MyAuthor', db_constraint=False)
    class MyAuthor(models.Model):
        name = models.CharField(max_length=20)

    3.断开关联的多对多手动创建关系表

    # 手动创建关系表可以让关系表可以拥有更多的自身的字段,同时通过关系表类名可以直接获取第三张表
    '''
    # ****
    # 1、和自动建立关系表类似,依然支持Django ORM连表查询语法(多对多借助关系表连表查询)
    class Book(models.Model):
        name = models.CharField(max_length=20)
        
    class Author(models.Model):
        name = models.CharField(max_length=20)
        
    class Book_Author(models.Model):
        book = models.ForeignKey(to="Book", null=True, on_delete=models.SET_NULL)
        author = models.ForeignKey(to='Author', null=True, on_delete=models.SET_NULL)
        time = models.DateField()
    '''

    2.
    class Book(models.Model): title = models.CharField(max_length=32, verbose_name="书名") # 自己创建第三张表,并通过ManyToManyField指定关联 class Author(models.Model): name = models.CharField(max_length=32, verbose_name="作者姓名") books = models.ManyToManyField(to="Book", through="Author2Book", through_fields=("author", "book")) # through_fields接受一个2元组('field1','field2'): # 其中field1是定义ManyToManyField的模型外键的名(author),field2是关联目标模型(book)的外键名。 class Author2Book(models.Model): author = models.ForeignKey(to="Author",null=True, on_delete=models.SET_NULL,db_constraint=False) book = models.ForeignKey(to="Book", null=True, on_delete=models.SET_NULL,db_constraint=False) class Meta: unique_together = ("author", "book")

     Django字段详解

  • 相关阅读:
    001.云桌面整体解决方案实施
    Netty基础招式——ChannelHandler的最佳实践
    架构设计之数据分片
    Go是一门什么样的语言?
    Jenkins汉化配置
    Window安装构建神器Jenkins
    uni-app&H5&Android混合开发三 || uni-app调用Android原生方法的三种方式
    如何使用Hugging Face中的datasets
    关于torch.nn.LSTM()的输入和输出
    pytorch中的nn.CrossEntropyLoss()计算原理
  • 原文地址:https://www.cnblogs.com/wangke0917/p/10491675.html
Copyright © 2020-2023  润新知