zoukankan      html  css  js  c++  java
  • 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)
    
  • 相关阅读:
    解决PKIX:unable to find valid certification path to requested target 的问题
    Linux 上的常用文件传输方式介绍与比较
    用VNC远程图形化连接Linux桌面的配置方法
    红帽中出现”This system is not registered with RHN”的解决方案
    linux安装时出现your cpu does not support long mode的解决方法
    CentOS SSH配置
    es6扩展运算符及rest运算符总结
    es6解构赋值总结
    tortoisegit安装、clon、推送
    es6环境搭建
  • 原文地址:https://www.cnblogs.com/chmily/p/11777985.html
Copyright © 2011-2022 走看看