zoukankan      html  css  js  c++  java
  • Django的ORM查询

    一、准备工作

    为了能够将查询到的结果,在日志中显示出来,我们需要简单配置下,灵感来源于Django的启动文件wsgi.py。

    只需简单几行,我们就能够在不启动项目的情况下,达到实验的目的。

    在主项目目录下新建test.py 文件

    配置如下

    import os
    import django
    # 参考wsgi.py
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'salary.settings')
    django.setup()
    # 访问数据,一定要写在上面四行之后
    from employee.models import Employee
    
    emps = Employee.objects.all() # 结果集,本句不发起查询
    print(type(emps))
    print(*list(emps), sep='
    ') # 所有员工

    到这里,准备工作做完了

     

    二、管理器对象

    Django会为模型类提供一个objects对象,它是django.db.models.manager.Manager类型,用于与数
    据库交互。当定义模型类的时候没有指定管理器,则Django会为模型类提供一个objects的管理器。
    如果在模型类中手动指定管理器后,Django不再提供默认的objects的管理器了。
    管理器是Django的模型进行数据库查询操作的接口,Django应用的每个模型都至少拥有一个管理器。
    用户也可以自定义管理器类,继承自django.db.models.manager.Manager,实现表级别控制。

     

    三、查询(惰性求值+缓存)

     

    切片

    qs = Employee.objects.all()[10:15]
    # LIMIT 5 OFFSET 10
    qs = Employee.objects.all()[20:30]
    # LIMIT 10 OFFSET 20

     

    结果集方法(pk指主键)

    名称
    说明
    all()
     
    filter()
    过滤,返回满足条件的数据
    exclude()
    排除,排除满足条件的数据
    order_by()
    排序,注意参数是字符串
    values()
    返回一个对象字典的列表,列表的元素是字典,字典内是字段和值的键值对
    mgr = Employee.objects
    # 结果集方法
    print(mgr.all())
    print(mgr.values())
    print(mgr.filter(pk=10010).values())
    print(mgr.exclude(emp_no=10001))
    print(mgr.exclude(emp_no=10002).order_by('emp_no'))
    print(mgr.exclude(emp_no=10002).order_by('-pk'))
    print(mgr.exclude(emp_no=10002).order_by('-pk').values())

     

    返回单个值的方法

    名称 说明
    get()
    仅返回单个满足条件的对象
    如果未能返回对象则抛出DoesNotExist异常;如果能返回多条,抛出
    MultipleObjectsReturned异常
    count()
    返回当前查询的总条数
    first()
    返回第一个对象
    last()
    返回最后一个对象
    exist()
    判断查询集中是否有数据,如果有则返回True
    # first()/last()方法比get温和,没有查询到结果时会返回none,并不会像get()那样报错
    # 单个值方法
    print(mgr.first())
    print(mgr.all().values().first())
    print(mgr.exclude(pk=10010).last())
    print(mgr.filter(pk=10010,gender=1).first())
    print(mgr.filter(pk=10010).values().first())
    print(mgr.count())
    print(mgr.exclude(pk=10010).count())

     

    字段查询(Field Lookup)表达式(类sql的where)

    名称 举例 说明
    exact
    filter(isdeleted=False)
    filter(isdeleted__exact=False)
    严格等于,可省略不写
    contains
    exclude(title__contains='天')
    是否包含,大小写敏感,
    等价于 like '%天%'
    startswith
    endswith
    filter(title__startswith='天')
    以什么开头或结尾,大小
    写敏感
    isnull
    isnotnull
    filter(title__isnull=False)
    是否为null
    iexact
    icontains
    istartswith
    iendswith
       
    in
    filter(pk__in=[1,2,3,100])
    是否在指定范围数据中
    gt、gte
    lt、lte
    filter(id__gt=3)
    filter(pk__lte=6 )
    filter(pub_date__gt=date(2000,1,1))
    大于、小于等
    year、month、
    day
    week_day
    hour、minute、
    second
    filter(pub_date__year=2000)
    对日期类型属性处理
    # 字段查询,相当于sql语句的where
    print(mgr.filter(emp_no__exact=10010))   # 就是等于,所以很少用exact。emp_no__exact=10010 相当于 emp_no=10010
    print(mgr.filter(pk__in=[10010,100009]))
    print(mgr.filter(last_name__startswith='P'))
    print(mgr.exclude(pk__gt=10003))

     

    Q对象

    虽然Django提供传入条件的方式,但是不方便,它还提供了Q对象来解决。
    Q对象是django.db.models.Q,可以使用&、|操作符来组成逻辑表达式。 ~ 表示not。

    print(mgr.filter(Q(pk__lt=10006)))  # 不如直接写print(mgr.filter(pk__lt=10006))
    # 下面几句一样 "与"
    print(mgr.filter(pk__gt=10003).filter(pk__lt=10006)) #
    print(mgr.filter(pk__gt=10003,pk__lt=10006))
    print(mgr.filter(pk__gt=10003) & mgr.filter(pk__lt=10006))
    print(mgr.filter(Q(pk__gt=10003),Q(pk__lt=10006)))
    print(mgr.filter(Q(pk__gt=10003) & Q(pk__lt=10006)))
    # 下面几句一样 "或"
    print(mgr.filter(pk__in=[10003,10006]))
    print(mgr.filter(pk=10003) | mgr.filter(pk=10006))
    print(mgr.filter(Q(pk=10003) | Q(pk=10006)))
    # 下面几句一样 "非"
    print(mgr.exclude(pk=10003))
    print(mgr.filter(~Q(pk=10003)))

     

    聚合、分组---aggregate() 返回字典,方便使用

    # 聚合
    print(mgr.filter(pk__gt=10010).count())
    print(mgr.filter(pk__gt=10010).aggregate(Count('pk'), Max('pk')))
    print(mgr.filter(pk__gt=10010).aggregate(Avg('pk')))
    print(mgr.filter(pk__gt=10010).aggregate(Max('pk'), min=Min('pk'))) # min=Min('pk') 别名
    
    # 分组
    print(mgr.filter(pk__gt=10010).aggregate(Count('pk')))
    s = mgr.filter(pk__gt=10010).annotate(Count('pk'))
    for x in s:
        print(x)
        print(x.__dict__)
    
    s = mgr.filter(pk__gt=10010).values('gender').annotate(Count('pk'))
    print(s)
    for x in s:
        print(x)
    
    # values()方法,放在annotate前就是指定分组字段,之后就是取结果中的字段。
    s = mgr.filter(pk__gt=10010).values('gender').annotate(c=Count('pk')).order_by('-c')
    print(s)
    for x in s:
        print(x)
    
    s = mgr.filter(pk__gt=10010).values('gender').annotate(Avg('pk'), c=Count('pk')).order_by('-c').values('pk__avg','c')
    print(s)
    for x in s:
        print(x)
  • 相关阅读:
    Java链接 Oracle11g R2
    MARS3.6 Programming
    相关分析
    统计学中的P值与显著性的意义
    Java的输入/输出操作
    SQL Server数据类型一览表
    Fragstats:使用R软件读取frag78b.asc文件
    收藏一下大牛的数据挖掘学习经验
    数据库系统概论(第四版)习题解答
    ArcGIS中的坐标系统定义与投影转换
  • 原文地址:https://www.cnblogs.com/soymilk2019/p/14782697.html
Copyright © 2011-2022 走看看