• Django聚合查询、分组查询、F与Q查询


    表查询

    基于django settings源码实现自己的项目
    配置文件的可插拔式设计
    	dir()
    	importlib
    	反射
    

    单表查询
        只要是queryset对象 就可以无限制的点击queryset对象的方法
    	13条
    		1.all()  # 查所有
    		2.filter()  # 根据条件过滤 多个条件之间是and关系
            3.get()  # 直接获取数据对象  查询条件不存在直接报错
            4.first()  # 取queryset的第一个数据对象
            5.last()  # 取queryset的最后一个数据对象
            6.exclude()  # 除此之外 
            7.values()  # queryset 类似于列表套字典
            8.values_list()  # queryset 类似于列表套元组
            9.count()  # 统计数据个数
            10.distinct()  # 一定要是完全一样的数据才能去重
            11.order_by()  # 排序 默认是升序 加负号就变成降序
            12.reverse()  # 反转 排序之后才能反转
            13.exists()  # 判断queryset是否有值 结果是个布尔值
            
    	神奇的双下线的查询
            price__gt
            price__lt
            price__gte
            price__lte
            price__in=[100,200,300]
            price__range=(200,800)
            title__contains  包含  模糊匹配
            title__icontains  忽略大小写
            publish_date__year  只针对年份
            publish_date__month  只针对月份
            title__startswith
            title__endswith 
    


    多表查询
        前期表准备
            图书管理系统
                一对多
                多对多
                一对一
            
    	外键字段的增删改查
            一对多字段
                create(publish_id=1)
                create(publish=publish_obj)
                
                update(publish_id=2)
                update(publish=publish_obj1)
                
                models.Publish.objects.filter(pk=2).delete()
                # orm外键默认是级联更新 级联删除的
            
            多对多字段
                # 朝第三张关系表中添加数据
                book_obj.authors.add(1)
                book_obj.authors.add(1,2,3,4)
                book_obj.authors.add(author_obj)
                book_obj.authors.add(author_obj,author_obj1,author_obj2)
                # 朝第三张表修改数据
                book_obj.authors.set((1,))
                book_obj.authors.set((1,2,3))
                book_obj.authors.set((author_obj,))
                book_obj.authors.set((author_obj,author_obj1))
                # 朝第三张表删除关系
                book_obj.authors.remove(1)
                book_obj.authors.remove(1,2,3,4)
                book_obj.authors.remove(author_obj)
                book_obj.authors.remove(author_obj,author_obj1)
                # 朝第三张表清空当前书籍对象所有的记录
                book_obj.authors.clear()
                
    	跨表查询
            正反向的概念:
                外键字段在谁那儿 谁就是正向
                没有外键字段的  就是反向
    

            口诀:
                正向查询按字段
                反向查询按表名小写
    


    		基于对象  # 子查询
                """
                步骤都是先获取一个数据对象
                然后利用对象点点点的方式查到锁对应的数据
                """
                # 正向
                book_obj.publish.name
                
                book_obj.authors.all()
                
                author_obj.author_detail.addr
                """
                外键字段所对应的数据 如果是单个 不需要加all
                如果是多个 需要加all()
                """
                # 反向
                publish_obj.book_set.all()
                
                author_obj.book_set.all()
                
                author_detail_obj.author.name
                """
                反向查询 数据如果是多个
                那么需要 表名小写_set.all()
                如果是一个  直接表名小写即可
                """ 
      
    		基于双下划綫  # 连表查询
                """
                left join
                right join
                inner join
                union
                """
                # 正向
                models.Book.objects.filter(title='python').values('publish__name')
                # 写外键字段publish之后 就会跨到publish表中  你想要该表的哪个字段对应的数据  就加__字段名获取
                
                models.Book.objecst.filter(pk=1).values('authors__name')
                
                models.Author.objects.filter(name='jason').values('author_detail__addr')
                
                models.Publish.objects.filter(pk=1).values('book__title')
                models.authors.objects.filter(pk=1).values('book__title')
                models.AuthorDetail.objects.filter(pk=1).values('author__name')
    

                # 反向
                
                models.Publish.objects.filter(book__title='python').values('name')
    

                """查询书籍id为1 的作者的 手机号"""
                models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
    
    
    
    聚合查询
        聚合函数
            from django.db.models import Max,Min,Sum,Count,Avg
            
            
    
    
    分组查询
    
    F与Q查询
    
    orm中常见字段
        AutoField(primary_key=True)
        CharField(max_length=32)   varchar(32)
        IntegerField()             int
        BigIntegerField()          long
        DateField()
            auto_now:每次修改数据的时候 都会更新该字段
            auto_now_add:只在创建数据的时候 才会自动将创建时间添加 后续不会再自动修改了
        DecimalField()
        BooleanField(Field)
            - 布尔值类型
            该字段在存储数据的时候 你只需要传布尔值即可
            对应到数据库中 会变成0/1
        TextField(Field)
            - 文本类型
            存大段文本
        EmailField(CharField)               varchar(...)
        FileField(Field)
            - 字符串,路径保存在数据库,文件上传到指定目录
            - 参数:
                upload_to = ""      上传文件的保存路径
                storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
    
        DecimalField(Field)
        - 10进制小数
        - 参数:
            max_digits,小数总长度
            decimal_places,小数位长度
    


    自定义char字段
        # 自定义char类型字段
        class MyCharField(models.Field):
            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
    

    如果你使用的是django2.X版本 你在建数据库表关系的时候
    你需要手动指定两个参数
        (你要手动告诉django  级联更新 级联删除  是否建外键约束)
        
        on_delete
        db_constraint
    

    !!!!!!!!!!碎片化学习!!!!!!!
    


    查询优化(面试比较喜欢问的)
        only与defer
    

        select_related和prefetch_related
    


    django orm中的事务操作
        ACID
            原子性
            一致性
            隔离性
            持久性
    

            commit
            rollback
        要么同时成功要么同时失败
        
        from django.db import transaction
        with transaction.atomic():
            # 在该代码块中所写的orm语句 同属于一个事务
        # 缩进出来之后自动结束
    

    聚合查询(aggregate)

    from django.db.models import Max,Min,Count,Avg,Sum   #查询总和,平均,最大,最小
    
    res = models.Book.objects.aggregate(Sum('price'))
    res1 = models.Book.objects.aggregate(Avg('price'))
    res2 = models.Book.objects.aggregate(Count('price'))
    res3 = models.Book.objects.aggregate(Max('price'))
    res4 = models.Book.objects.aggregate(Min('price'))
    res5 = models.Book.objects.aggregate(Max('price'),Min('price'),Count('pk'),Avg('price'),Sum('price'))  #也可以放在一个里面写
    

    分组查询 (annotate)

     1.统计每一本书的作者个数
    
    from django.db.models import Max, Min, Count, Avg, Sum
    
    res = models.Book.objects.annotate(author_num = Count('authors')).values('author_num','title')
     #book表根据authors分组求和,author_num是取的别名,values是控制台打印的值
    2.统计每个出版社卖的最便宜的书的价格
    
    res = models.Publish.objects.annotate(mmp = Min('book__price')).values('name','mmp')
    3.统计不止一个作者的图书
    
    res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1)
    4.查询每个作者出的书的总价格
    
    res = models.Author.objects.annotate(sp=Sum('book__price')).values('name','sp')
    

    F查询与Q查询

    F查询的本质就是从数据库中获取某个字段的值,之前查询等号后面的条件都是我们人为输入的,现在变成了需要从数据库中获取数据放在等号后面

    查询库存量大于卖出量的书籍

    from django.db.models import F
    res = models.Book.objects.filter(kucun__gt=F('maichu')) #kucun和maichu都是Book表的字段
    

    将书籍库存数全部增加1000

    models.Book.objects.update(kucun=F('kucun')+1000)
    

    把所有书名后面加上'新款'

    from django.db.models.functions import Concat
    from django.db.models import Value
    
    ret3 = models.Book.objects.update(title=Concat(F('title'), Value('新款')))
    models.Book.objects.update(title = F('title')+'新款')  # 不能这么写
    

    Q查询 (filter里面条件都是与,Q支持与或非)

    查询书籍名称是三国演义或者价格是444

    from django.db.models import Q
    res = models.Book.objects.filter(title='三国演义',price=444.44)  # filter只支持and关系
    res1 = models.Book.objects.filter(Q(title='三国演义'),Q(price=444))  # 如果用逗号 那么还是and关系
    res2 = models.Book.objects.filter(Q(title='三国演义')|Q(price=444))   #或者关系
    res3 = models.Book.objects.filter(~Q(title='三国演义')|Q(price=444))  #查询除了title是三国演义,或者价格是444的书籍
    

    Q的高级用法

    from django.db.models import Q
    q = Q()
    q.connector = 'or'  # 修改查询条件的关系   默认是and
    q.children.append(('title__contains','三国演义'))  # 往列表中添加筛选条件
    q.children.append(('price__gt',444))  # 往列表中添加筛选条件
    res = models.Book.objects.filter(q)  # filter支持你直接传q对象  但是默认还是and关系
    print(res)
    
  • 相关阅读:
    Jmeter监控服务器性能
    三种主流的WebService实现方案(REST/SOAP/XML-RPC)简述及比较
    从0到1搭建移动App功能自动化测试平台(0):背景介绍和平台规划
    Jmeter监控系统等资源,ServerAgent端口的修改
    Performance plugin离线安装
    Oracle定义常量和变量
    通过FTP将一个数据文件从A服务器下载到B服务器的整个过程
    Oracle使用%rowtype变量存储一行数据
    Oracle使用%type类型的变量输出结果
    mdf与ldf文件如何还原到SQLserver数据库
  • 原文地址:https://www.cnblogs.com/chmily/p/11777985.html
Copyright © 2020-2023  润新知