美文网首页
58.2-Django模型之查询集切片过滤器

58.2-Django模型之查询集切片过滤器

作者: BeautifulSoulpy | 来源:发表于2020-08-12 22:49 被阅读0次

    总结:

    1. 查询管理器一般至少定义一个 才可以查询;
    2. 浏览器端发来的数据都不可信;
    3. 结果集本身就是一个 缓存 ;
    4. _str_ 是给用户看的,_repr_则是给开发者看的;例如:
      str(dog) 'i am kitty'
      repr(dog) 'Animal:name is kitty'
    5. 字段命名 禁止使用__;

    模型操作

    管理器对象

    Django会为模型类提供一个objects对象,它是django.db.models.manager.Manager类型,用于与数据库交互(对数据库进行 增删改查)。

    Django 的一个强大的功能是它的对象关系映射Object-Relational Mapper(ORM),它允许你就像使用 SQL 一样去和你的数据库交互。事实上,Django 的 ORM 就是创建 SQL 去查询和操作数据库的一个 Python 式方式,并且获得 Python 风格的结果。 我说的是一种方式,但实际上,它是一种非常聪明的工程方法,它利用了 Python 中一些很复杂的部分,而使得开发者更加轻松。

    当定义模型类的时候没有指定管理器,则Django会为模型类提供一个objects的管理器。
    如果在模型类中手动指定管理器后,Django不再提供默认的objects的管理器了。
    管理器是Django的模型进行数据库查询操作的接口,Django应用的每个模型都至少拥有一个管理器。

    Django ORM

    数据的校验validation是在对象的Save、update方法上


    1. 查询

    1.1 查询集

    查询会返回结果的集, 它是django.db.models.query.Query Set类型。
    它是惰性求值, 和sql alchemy一样。结果就是查询的集。
    它是可迭代对象。

    # blog/user/urls  # 设置访问路劲;
    from django.conf.urls import url
    from .views import reg,show
    
    urlpatterns = [
        url(r'^reg$',reg),
        url(r'^show$',show)
        ]
    
    # blog/user/show  中增加 
    def show(request):          # 方法的使用方式各不相同;
        query = User.objects.all()   # objects
    
        return JsonResponse({})
    #-------------------------------------------------------
    {}
    

    1、惰性求值:
    创建查询集不会带来任何数据库的访问,直到调用方法使用数据时,才会访问数据库。在迭代、序列化、if语句中都会立即求值。

    2、缓存:
    每一个查询集都包含一个缓存,来最小化对数据库的访问。

    新建查询集,缓存为空。首次对查询集求值时,会发生数据库查询,Django会把查询的结果存在这个缓存中,并返回请求的结果,接下来对查询集求值将使用缓存的结果。

    观察下面的2个例子是要看真正生成的语句了

    1. 没有使用缓存,每次都要去查库,查了2次库
      [user.name for user in User.objects.all()]
      [user.name for user in User.objects.all()]
    [u for u in User.objects.all()]
    [u for u in User.objects.all()]
    
    1. 下面的语句使用缓存,因为使用同一个结果集,查一遍;
      qs = User.objects.all()
      [user.name for user in qs]
      [user.name for user in qs]
      [u for u in users] # 查一遍
      [u for u in users]
    1.2 限制查询集(切片)

    为了不对数据库多次查询,
    http://127.0.0.1:8000/admin/user/user/ 增加2个用户

    查询集对象可以直接使用索引下标的方式(不支持负索引),相当于SQL语句中的limit和offset子句。
    注意使用索引返回的新的结果集,依然是惰性求值,不会立即查询。

    qs = User.objects.all()[20:40]
    # LIMIT 20 OFFSET 20
    
    users = User.objects.all()[1:]
    print(users)# objects
    #---------------------------------------
    <QuerySet [<User 6 jerry>, <User 7 ben>]>
    
    1.3 过滤器

    返回查询集的方法,称为过滤器,如下:
    User.objects.-------

    名称 说明
    all()
    filter() 过滤,返回满足条件的数据
    exclude() 排除,排除满足条件的数据
    order_by()
    values() 返回一个对象字典的列表,列表的元素是字典,字典内是字段和值的键值对

    filter(k1=v1).filter(k2=v2) 等价于 filter(k1=v1, k2=v2)
    filter(pk=10) 这里pk指的就是主键, 不用关心主键字段名,当然也可以使用使用主键名filter(emp_no=10) 返回单个值的方法

    // 
    users = User.objects.all()
    print(users.values())# objects
    # ------------------------------------------------------------------
    <QuerySet [{'id': 1, 'name': 'tom', 'email': 'tom@magedu.com', 'password': 'tom'}, {'id': 6, 'name': 'jerry', 'email': 'jerry@magedu.com', 'password': 'jerry'}, {'id': 7, 'name':
     'ben', 'email': 'ben@a.com', 'password': 'ben'}]>
    
    名称 说明
    get() 仅返回单个满足条件的对象
    如果未能返回对象则抛出DoesNotExist异常;如果能返回多条,抛出MultipleObjectsReturned异常
    count() 返回当前查询的总条数
    first() 返回第一个对象
    last() 返回最后一个对象
    exist() 判断查询集中是否有数据,如果有则返回True
    user = User.objects.filter(email=email).get() # 期待查询集只有一行,否则抛出异常
    user = User.objects.get(pk=2) # 返回不是查询集,而是一个User实例,否则抛出异常
    user = User.objects.get(id=1) # 更多的查询使用主键,也可以使用pk=1
    user = User.objects.first() # 使用limit 1查询,查到返回一个实例,查不到返回None
    user = User.objects.filter(pk=3, email=email).first() # and条件
    
    1.4 字段查询(Field Lookup)表达式

    字段查询表达式可以作为filter()、exclude()、get()的参数,实现where子句。
    语法: 属性(字段)名称__比较运算符=值
    注意:属性名和运算符之间使用双下划线
    比较运算符如下

    名称 举例 说明
    exact filter(is deleted=False)
    filter(is deleted_ _exact=False)
    严格等于,可省略不写
    contains exclude(title__contains='天') 是否包含,大小写敏感,等价于like'%天%'
    statswith
    endswith
    filter(title__starts with='天' 以什么开头或结尾,大小写敏感
    isnull
    isnotnull
    filter(title__is null=False) 是否为null
    iexact
    icontains
    istartswith
    i ends with
    i的意思是忽略大小写
    in filter(pk_in=[1, 2, 3, 100] ) 是否在指定范围数据中
    gt、gte 大
    It、Ite 小
    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) 对日期类型属性处理
    1.5 Q对象

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

    from django.db.models import Q
    User.objects.filter(Q(pk__lt=6)) # 不如直接写User.objects.filter(pk<6)
    User.objects.filter(pk__gt=6).filter(pk_lt=10) # 与
    User.objects.filter(Q(pk_gt=6) & Q(pk_lt=10)) # 与
    User.objects.filter(Q(pk=6) | Q(pk=10)) # 或
    User.objects.filter(~Q(pk__lt=6)) # 非
    

    可使用&|和Q对象来构造复杂的逻辑表达式
    过滤器函数可以使用一个或多个Q对象
    如果混用关键字参数和Q对象,那么Q对象必须位于关键字参数的前面。所有参数都将and在一起

    相关文章

      网友评论

          本文标题:58.2-Django模型之查询集切片过滤器

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