美文网首页
Django ORM概述

Django ORM概述

作者: EL33 | 来源:发表于2019-02-24 22:18 被阅读0次

    一、什么是Django ORM

    ORM--(Object Relational Mapping)关系对象映射

    QuerySet表示数据库中的对象集合。可以有0、1或多个过滤器,在SQL中,QuerySet等于SELECT语法过滤器是限制子句,如WHERE或LIMIT

    那么怎么查看所执行的SQL语句呢,query.__str__(),或者print(QuerySet.query)

    In [1]:Teacher.objects.all().query.__str__()
    Out[1]: 'SELECT `teacher`.`id`, `teacher`.`name` FROM `teacher`'
    

    二、基础操作(增删改查)

    2.1、增

    取对象,赋值然后,save()

    >>> from school.models import *
    >>> teacher = Teacher()
    >>> teacher.name = "懒得卡"
    >>> teacher.save()
    

    2.2、删

    delete(),批量删除就查询再删除

    >>> Teacher.objects.get(pk=1).delete()
    

    2.3、改

    改得话有两种,取到具体某一个QuerySet对象,重新赋值然后save(),第二种就是查询后update(key="newvalue")

    2.4、查

    2.4.1、基础查询

    • 检索所有对象
      all()方法

        >>> Teacher.objects.all()
      
    • 检索特定对象
      filter() 返回QuerySet包含与给定查找条件匹配的新对象,是一个类似于列表的类型,所以只存在单个元素时候,也需要取索引.
      exclude() 返回QuerySet包含与查找条件不匹配的新对象

    • 检索单个对象
      get() 如果没有查询匹配的结果,get()则会引发DoseNotExist异常,有多个结果也会返回ObjectReturned异常

    • 字段查找

      精确匹配: __exact = "匹配内容",无实际作用

      忽略大小写匹配: __iexact = "匹配内容"

      包含匹配条件: __contains = "匹配内容", 同样的也有icontains

      模糊匹配: __startswith = "以内容开头",__endswith = "以内容结尾",同样有忽略大小写的,在前面加i就行

      正则匹配: __regex ="r'正则表达式匹配内容'",忽略大小写iregex

      比较匹配: 大于__gt,小于__lt,大于等于__gte,小于等于__lte

      __in = ["true","false","hahah"]__range(1,3)范围

      获取默认为空/不为空的字段: __isnull = True/False

    • 跨越关系的查找
      使用跨模型的相关字段,直接使用字段名称,用双下划线分割,可多次使用
      要使用"反向"关系,只需要使用模型的小写名称即可.

    • F查询(解决字段之间匹配的问题)

        >>> from django.db.models import F
        >>> # e.g. 要查找作者姓名和博客名称相同的所有条目
        >>> Entry.objects.filter(author__name=F('blog__name'))
      

      F对象支持+ , - , * , / , %(模运算,求余), ^(幂运算)和跨越关系等

        >>> e.g. 查找点赞数大于评论加收藏数的所有条目
        >>> Entry.objects.filter(goods__gt=F('comments')+F('collect'))
      

      对于日期和时间型的字段,可以用timedelta对象来实现加减

        >>> from datetime import timedelta
        >>> e.g. 查找发布时间超过3天的文章
        >>> Entry.objects.filter(date__gt=F('pub_date')+timedelta(day=3))
      
    • Q查询(解决"或"的问题)
      & , | , ~ 运算符,在两个Q对象上使用与或非运算符时,它会产生一个新的Q对象

        >>> from django.db.models import Q
        >>> Q(question__startswith="who") | Q(question__startswith="what")
      

    2.4.2、聚合(Aggretations)

    Django提供了两种生成聚合的方法

    • aggregate()聚合
      常见的聚合函数有Avg/Count/Sum/Max/Min等等

        >>> from django.db.models import Count
        >>> Entry.objects.all().aggregate(num_books=Count("book")).values("num_books")
        { 'num_books':27 }
        >>> # 这里的all()可以省略掉,就变成了
        >>> Entry.objects.aggregate(num_books=Count("book")).values("num_books")
        >>> # num_books为别名,类似于SQL里面的as
      

      aggregate()支持在聚合函数内内联Q查询

        >>> e.g. 统计整个班男生和女生的数量(gender为0为男生,1为女生)
        >>> Student.objects.aggregate(mail=Count("gender",filter=Q(gender=0)),famail=Count("gender",filter=Q(gender=1)))
      
    • annotate()分组
      分组和MySQL中的分组不太一样,它默认对所用对象的id进行分组,比如Student.objects.annotate(...)就是将学生按学生id进行分组了已经.同样的,分组一定要进行聚合操作</br>
      所以在反复练习之后,对用那个对象进行查询就很明显了,例如查询AAA大于/小于/其他条件的BBB的CCC项那就是使用BBB的对象了,BBB.objects.(...)

    • order_by()排序
      排序也没要多的需要讲的,order_by("-name")降序,默认排序方式为由低到高

    • values()/values_list() 获取查询结果的某一或者某些列,values_list获取的值为一个元组

    • distinct() 从返回结果中剔除重复记录.这个不属于聚合,但是在学习这些的时候遇到了

    相关文章

      网友评论

          本文标题:Django ORM概述

          本文链接:https://www.haomeiwen.com/subject/smliyqtx.html