orm中的聚合函数,分组,F/Q查询,字段类,事务

一、聚合函数

  • 聚合函数单独使用意义不大,一般与分组联用
  • 没有分组其实默认整体就是一组

  • 常用的聚合函数有:Max Min Sum Avg Count

1. 基础语法

  • 聚合函数要先导入才能使用

    from django.db.models import Max, Min, Sum, Count, Avg
    
    # 温馨提示:只要跟数据库相关的功能 基本上都在django.db.models里面
    # 如果不在 可能直接在django.db里面
  • 用关键字aggregate实现

    例子:res = models.Book.objects.aggregate(mr = Max('price'))
    
    mr 为该聚合字段的名字,随便取。也可以不命名,django会自动命名为: 表名__max

2. Max Min Sum Avg Count用法

(1) Max()/Min()

# 1.筛选出价格最高的书籍的
from django.db.models import Max, Min, Sum, Count, Avg
res = models.Book.objects.aggregate(mr = Max('price'))
res1 = models.Book.objects.aggregate(mr = Min('price'))

(2)Avg()

# 2.求书籍总价格
from django.db.models import Max, Min, Sum, Count, Avg
res = models.Book.objects.aggregate(sm = Sum('price'))

(3)Count()

# 3.求书籍平均价格
from django.db.models import Max, Min, Sum, Count, Avg
res = models.Book.objects.aggregate(av = Avg('price'))

(4)聚合函数联用

# 4.一起使用
from django.db.models import Max, Min, Sum, Count, Avg
res = models.Book.objects.aggregate(Max('price'),Min('price'),Sum('price'),Count('price'),Avg('price'))

二、分组查询

  • 分组一般配合聚合函数使用
  • django中models后面点什么,就按照什么分组。若点的是模型类(表),则默认以该表的主键分组

  • 关键字:annotate

1. 分组查询实例

  • 以下查询到的都是queryset对象
# 1. 统计每一本书的作者个数 书名 和对应的作者人数
res = models.Book.objects.annotate(author_num=Count('authors__id')).values('title','author_num')

# 2. 统计出每个出版社卖的最便宜的书的价格  出版社的名字 价格
res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price')

# 3. 按照其他字段分组
res = models.Publish.objects.values('想要分组的字段名').annotate(min_price=Min('book__price')).values('name','min_price')


# 4. 统计不止一个作者的图书
    # 先拿书及对应的作者数
    # 再筛选出大于一的图书  书名 作者数目
res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('title','author_num')


# 5. 查询各个作者出的书的总价格  作者名字  总价格
res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price')

三、F与Q查询

  • F与Q查询前要先导入才能使用

    from django.db.models import F,Q

1. F查询实例

  • 当条件中的运算符号的右边为表中其他字段时,使用F方法来组成该条件右边的部分。user_id > book_id中的book_id
from django.db.models import F  # 一定要先导入
# 1. 查询库存数大于卖出数的书籍
res = models.Book.objects.filter(ku_cun__gt = F('mai_cun')).values('title')  # 后面的条件是来自于数据库的其他字段值


# 2. 将所有书的价格上涨100块
models.Book.objects.all().update(price=F('price') + 100)


# 3.将所有书的名称后面全部加上 "新款" 后缀 (了解知识点)
    # 操作字符串数据需要借助于Concat方法
from django.db.models.functions import Concat
from django.db.models import Value
ret3 = models.Book.objects.update(title=Concat(F('title'), Value('新款')))

2. Q查询实例

  • Q查询主要用来改变条件与条件之间的逻辑关系。即 and/or/not
from django.db.models import Q  # 一定要先导入

# 1.查询一下书籍名称是三国演义 或者 库存数是500的书籍
res = models.Book.objects.filter(title='三国演义',ku_cun=500)  # and关系
res1 = models.Book.objects.filter(Q(title='三国演义'),Q(kun_cun=500))  # Q包裹之后逗号还是and关系
res = models.Book.objects.filter(Q(title='三国演义') | Q(ku_cun=500))  #  |就是or的关系
res = models.Book.objects.filter(~Q(title='三国演义') | Q(ku_cun=500))  #   ~就是not关系
  • Q方法的高级用法
from django.db.models import Q

q = Q()
q.connector = 'or'  # 默认是and  可以改成or
q.children.append(('title','三国演义'))
q.children.append(('ku_cun__gt',500))

# 查询书名是三国演义或者库存数量大于500的书籍
res1 = models.Book.objects.filter(q)
res2 = models.Book.objects.filter(~q)  # 取反

四、orm字段及参数

1. 常见的orm字段

CharField     varchar
IntegerField   int
BigIntegerField   bigint
EmailField    varchar(254)
DateField  
DateTimeField 
'''
DateField 和 DateTimeField 中都有两个参数 auto_now 和 auto_now_add
auto_now:每次修改数据的时候,不管你有没有指定修改时间字段,时间字段都会自动将当前时间修改成这次修改的当前时间,即实时更新
auto_now_add:在创建数据的时候,会将当前时间自动记录,之后不会自动修改,除非你人为指定修改
'''
AutoField     auto_increment    
BooleanField    布尔值 
TextField  专门用来存大段文本
        
FileField  专门用来文件路径字符串   如:'/etc/data/a.txt'   
            upload_to = 本地一个路径
            给该字段传值的时候 直接传文件对象
            会自动将文件对象保存到upload_to后面指定的文件路径中
            然后将路径保存到数据库
        
DecimalField(Field)
  - 10进制小数
  - 参数:
    max_digits,小数总长度
    decimal_places,小数位长度

2. 自定义字段

  • 自定义char字段实例

    
    class MyCharField(models.Field):  # 继承models中字段类
      def __init__(self,max_length,*args,**kwargs):
          self.max_length = max_length
          # 重新调用父类的方法
          super().__init__(max_length=max_length,*args,**kwargs)  # 一定要以关键字参数传入
    
      def db_type(self, connection):
          return 'char(%s)'%self.max_length

五、orm中的事务操作

  • 要先导入才能使用事务

    from django.db import transaction

1. 开启/关闭事务

# with 和文本操作中的with管理上下文功能一样,可以自动关闭事务

with transaction.atomic():
    # 在缩进的代码中书写数据库操作
    # 该缩进内的所有代码 都是一个事务
    pass

猜你喜欢

转载自www.cnblogs.com/Mcoming/p/11953154.html