• Python学习---ORM查询之基于对象的正向/反向/聚合/分组/Q/F查询


    ORM查询之基于对象的正向查询与反向查询

    对象形式的查询

    # 正向查询

        ret1=models.Book.objects.first()
        print(ret1.title)
        print(ret1.price)
        print(ret1.publisher)
        print(ret1.publisher.name)  # ret1.publisher是book属性,是Publish对象,非queryset集合

    # 反向查找

    ret2=models.Publish.objects.last()
        print(ret2.name)
        print(ret2.city)

    #如何拿到与它绑定的Book对象呢?

        print(ret2.book_set.all())  # ret2.book_set是一个queryset集合,all()可以省略
        print(ret2.book_set.all().values('title').distinct())  # 去重

    ORM查询之基于条件的正向查询与反向查询

    单表条件查询[双下划线实现表关联]:使用逗号分隔可以实现and的条件查询

    #    models.Book.objects.filter(id__lt=10, id__gt=1)      # 获取id大于1 且 小于10的值
    #    models.Book.objects.filter(id__in=[11, 22, 33])      # 获取id等于11、22、33的数据
    #    models.Book.objects.exclude(id__notin=[11, 22, 33])  # not in
    #    models.Book.objects.filter(title__contains="Python") # 模糊匹配
    #    models.Book.objects.filter(name__icontains="ven")    # icontains大小写不敏感
    #    models.Book.objects.filter(id__range=[1,12])         # 范围bettwen and
    #    startswith,istartswith, endswith, iendswith,        # 以XXX开始/XXX结束

    多表条件关联查询[双下划线实现表关联]

    一对多[正向查询]: 使用逗号分隔可以实现and的条件查询,filter和values里面均可使用双下划线

    #  models.Book.objects.filter(title='Python',id=5).values('publish__name').distinct()  
        # [{'publisher__city': '北京'}]  publish__name这里的Book里面的publish属性
    #  models.Book.objects.filter(publish__id=5).values('title').distinct()  
        # Book查找出版社ID=5的书的名字
    #  models.Book.objects.filter(publish__id=5).values('publish_name').distinct()  
        # Book查找出版社ID=5的出版社的名字

    一对多[反向查询]:使用逗号分隔可以实现and的条件查询,filter和values里面均可使用双下划线

    #  models.Publish.objects.filter(book__title='Python',book_id=5).values('name') .distinct()  
        # [{'name': 'H出版社'}] 查找跟Publish相关的Book的内容,book__title中的book就是Publish的关联表名

    多对多[正向查询]:使用逗号分隔可以实现and的条件查询

    #  models.Book.objects.filter(title='Python').values('author__name ') .distinct()  
    #  models.Book.objects.filter(author__name='FTL').values('title') .distinct()  

    多对多[反向查询]:使用逗号分隔可以实现and的条件查询

     #  models.Author.objects.filter(book__title='Python').values('name') .distinct() 

    注意:

    1、正向查找的book__title中的book是表名Book

    2、正向查找的publish__city或者author__name中的publish,author是book表中绑定的字段【Book里面的属性】

    3、一对多和多对多在这里用法没区别

    ORM之聚合查询与分组查询

    ORM之聚合查询与分组查询

    聚合查询: aggregate(*args,**kwargs):可通过filter/Values过滤后聚合

    通过对QuerySet进行计算,返回一个聚合值的字典。aggregate()中每一个参数都指定一个包含在字典中的返回值[键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的],即在查询集上生成聚合。

    from django.db.models import Avg,Min,Sum,Max
    >>> Book.objects.all().aggregate(Avg('price'))
    {'price__avg': 34.35}     # 系统定义名称
    >>> Book.objects.all().aggregate (average_price=Avg('price'))
    {'average_price': 34.35}     # 自定义了名称
    >>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))  # 其他查询

    分组查询:annotate(*args,**kwargs):可通过filter/Values过滤后分组

    可以通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值(也可以是平均值或总和),即为查询集的每一项生成聚合。

    from django.db.models import Avg,Min,Sum,Max
    >>> Book.objects.values('author_name').annotate(Sum('price')) # 根据作者名分组后计算每个作者price

    ORM之 F查询与Q查询

    F查询: 只能适用于IntegerFiled  【使用了F查询,默认值是0】

    from django.db.models import F
    models.Book.objects.update(num=F('num') + 100)  

    Q查询:

    from django.db.models import Q
    #1 Q对象(django.db.models.Q)可以对关键字参数进行封装,从而更好地应用多个查询
        q1=models.Book.objects.filter(Q(title__startswith='P')).all()
    # 2、可以组合使用&,|操作符,当一个操作符是用于两个Q的对象,它产生一个新的Q对象。
        q2=models.Book.objects.filter(Q(name='HHH')|Q(name='FTL')).all()
        # 3、Q对象可以用~操作符放在前面表示否定,也可允许否定与不否定形式的组合
        Q(title__startswith='P') | ~Q(pub_date__year=2005)
    # 4、应用:
        Book.objects.get(
             Q(title__startswith='P') and
            (Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))
        )
    # 5、Q对象可以与关键字参数查询一起使用,不过一定要把Q对象放在关键字参数查询的前面。
        # 正确:
        Book.objects.get(
            Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
            title__startswith='P')
        # 错误:
        Book.objects.get(
            question__startswith='P',
            Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

    Q的信息补充

    # 方式一: 直接用,不能动态实现
            models.UserInfo.objects.filter(Q(Q(username=u)&Q(pwd=p))|Q(Q(emial=u)&Q(pwd=p)))
    # 方式二: 创建Q对象且指定连接connector  【适用于多个元素,因为可用for循环,可动态循环】
            con = Q()
            
            q1 = Q()
            q1.connector = 'AND'
            
            q1.children.append(('email', e))
            q1.children.append(('password', p))
            # Q(Q(email=e)&Q(pwd=p))      
            
            q2 = Q()
            q2.connector = 'AND'
            q2.children.append(('username', _value_dict['user']))
            q2.children.append(('password', _value_dict['pwd']))
            # Q(Q(username=u)&Q(pwd=p))
            
            con.add(q1, 'OR')
            con.add(q2, 'OR')
            
            models.UserInfo.objects.filter(con)
    

      另外:

    如果传递过来一个字典:那就可以进行组合搜索:
    q1 = Q()
    q2.connector = 'AND'
    dict = {'id':1, 'username':'hhh', 'sex':'male', 'age':18}
    for k,v in dict:
        q1.children.append((k, v))    #  此时字典里面的所有值进行and组合查询
    

      

  • 相关阅读:
    浅析Java8新特性-Optional方法介绍(Optional.ofNullable-构造方法、map-逐层安全地拆解value、filter-过滤值、orElse/orElseThrow-最终返回、stream-转为流)及常用实践(仅作为方法返回值、清晰地表达返回值中没有结果的可能性、勿滥用Optional)、Optional的设计思想实现
    浅析Java8新特性-新的日期和时间API:起初时间存在的问题(非线程安全、设计乱、时区处理麻烦)、日期时间(LocalDate/LocalTime/LocalDateTime)、时间戳(Instant)、时间差(Duration/Period)、TemporalAdjuster时间矫正器、LocalDateTime 与 Date 互转、时间先后判断/MonthDay类的使用(生日检查)
    浅析 Employee::new / String[]::new 是什么意思?Java8新特性-方法引用、构造器引用、数组引用的了解及使用
    浅析HTTP的Referer含义理解、Referer作用(记录访问来源、防盗链、防止恶意请求)、Referrer Policy引用策略的9个值及设置用法、什么情况会导致空Referer
    浅析Java8新特性-四大内置核心函数式接口 :消费型Consumer(void accept)、供给型Supplier(T get)、函数型Funciton(R apply)、断言型Predicate(boolean test)
    浅析Java Lambda表达式、如何理解Lambda、如何使用Lambda简化代码(结合stream处理遍历、配合Optional优雅的处理null情况)
    【原文】linux systemctl命令详解
    [转]解决Ubuntu DNS覆盖写入127.0.0.53
    mysql 安装
    【转】lvextend 无法使用 virtualbox 扩容的vdi
  • 原文地址:https://www.cnblogs.com/ftl1012/p/9399299.html
Copyright © 2020-2023  润新知