zoukankan      html  css  js  c++  java
  • django中数据库ORM操作

    django一对多关系中,为了实现按照一端查询多端,之前都是用extra操作符,经过查看官方文档还有in这个操作符,用这个实现更简单。直接上代码:

    根据查询条件模糊查询所有符合条件的机架列表,然后根据机架列表查出相应的设备,之前是用下面这种实现方式:

    [python] view plain copy
     
    1. rackid = request.POST['rackid']  
    2. retdir['rackid'] = rackid  
    3. racks = Rack.objects.filter(rackid__icontains = rackid)  
    4. ids = ""  
    5. for rack in racks:  
    6.     ids += str(rack.id) + ","  
    7. ids = ids[0:-1]  
    8. if ids == None or ids == '':  
    9.     ids = '0'  
    10. equipments = Equipment.objects.extra(where=['rack_id IN ('+ ids +')'])  


    现在用in操作符,实现更简单,效率更高:

    [python] view plain copy
     
    1. rackid = request.POST['rackid']  
    2. retdir['rackid'] = rackid  
    3. racks = Rack.objects.filter(rackid__icontains = rackid)  
    4. equipments = Equipment.objects.filter(rack__in = racks)  


    其中机架跟设备是一对多的关系。

    参考官方文档:

    跨关系查找

    ###补充 

    MyModel.objects.create(**data_dict)  传入这个dict数据,但前提是: 字典数据里面的key 字段一定要与model中定义的field 对应,否则就会报错

    Django 提供一个有力且直观的方法来“追踪”查找中的关系,即会在后台自动处理 SQL 中的 JOIN 。要跨越一个关系,只要使用跨模块的关联字段即可,并用两个下划线分隔,直到得到你想要的字段为止。

    以下例子可以获得名称为 'Beatles Blog' 的 Blog 的所有条目。

    >>> Entry.objects.filter(blog__name__exact='Beatles Blog')
    

    这种跨越的深度是无限的。

    跨越也可以是反向的。要指向一个“反向”的关系,请使用模型的小写名称。

    下例可以获得至少一个条目的头条包含 'Lennon' 的所有Blog 对象:

    >>> Blog.objects.filter(entry__headline__contains='Lennon')
    

    如果你跨越了多重关系并且其中的一个模型没有符合条件的值,那么 Django 会把模型视作空对象(即所有值为 NULL ),而不是非法对象。因此在前述情况下不会引发错误。例如:

    Blog.objects.filter(entry__authors__name='Lennon')
    

    假设有一个相关联的 作者``( Author )模型,如果没有 ``作者 与任何一个条目关联,那么就会视作也没有名称 与之关联。这样处理比因为作者 缺失而引发错误要好。通常这也是你想要的处理方式。唯一会产生混淆的是当你使用isnull 的时候。就象下例:

    Blog.objects.filter(entry__authors__name__isnull=True)
    

    会返回包括 名字 为空的 作者 和 作者 为空的条目 两种情况的Blog 对象。如果你不希望包括后一种情况的对象,你可以这样写:

    Blog.objects.filter(entry__authors__isnull=False,
            entry__authors__name__isnull=True)
    

    跨越多值关系

    当你基于一个 多对多字段 对象或一个反向外键 过滤时,有两种不同的过滤方法值得注意。对于博客 与条目 关系( 博客 对于条目 是一对多关系),我们可能会想要查找一个博客,这个必须博客包括一个符合以下条件的条目:在条目的头条中包含"Lennon" 字样,并且发布日期为 2008 年。或者我们也可以会想要查找一个博客,这个博客必须符合以下条件:包含一个头条中有"Lennon" 字样的条目,并且包含一个发布日期为 2008 年的条目。因为一个博客 对应于多个条目 ,所以上述两种查询都是可能的,在特定情况下都是有用的。

    同样,一个 多对多字段 也会引发类似情况。例如,假设一个条目 字段有一个名为标记 ( tags )的多对多字段。我们可以会想要查找既有"music" 标记又有"bands" 标记的条目。或者我们也可能会想要查找标记为 "music" ,状态为"public" 的条目。

    对于上述两种方法, Django 中的 filter() 和exclude() 使用相同的方式来处理。在一个filter() 中的所有条件必须同时符合。在连续的filter() 中的条件对于多值关系情况下,这些条件是并列的(都对应于主模型的对象),而不是嵌套的(对应于前一个filter() 产生的对象)。

    都迷糊了吧,来一个例子清醒一下。要查找一个博客,这个必须博客包括一个符合以下条件的条目:在条目的头条中包含 "Lennon" 字样,并且发布日期为 2008 年。即条目必须同时符合两个条件。我们这样写:

    Blog.objects.filter(entry__headline__contains='Lennon',
            entry__pub_date__year=2008)
    

    要查找一个博客,这个博客必须符合以下条件:包含一个头条中有 "Lennon" 字样的条目,并且包含一个发布日期为 2008 年的条目。但对于同一个条目不一定要同时符合两个条件。我们这样写:

    Blog.objects.filter(entry__headline__contains='Lennon').filter(
            entry__pub_date__year=2008)
    

    在第二个例子中,第一个过滤器限定了特定条件的博客,第二个过滤器 进一步 限定了同时符合第二个条件的博客。匹配第二个过滤器的条目不一定匹配第一个过滤器。两个过滤器的条件都是针对某个博客而言的,而不是针对某个条目而言的。

    以上方式也同样用于 exclude() 。

    数据库操作API:

    类型描述
    exact 精确匹配: polls.get_object(id__exact=14).
    iexact 忽略大小写的精确匹配: polls.objects.filter(slug__iexact="foo") 匹配 fooFOOfOo, 等等.
    contains 大小写敏感的内容包含测试: polls.objects.filter(question__contains="spam") 返回question 中包含 "spam" 的所有民意测验.(仅PostgreSQL 和 MySQL支持. SQLite 的LIKE 语句不支持大小写敏感特性. 对Sqlite 来说, contains 等于 icontains.)
    icontains 大小写不敏感的内容包含测试:
    gt 大于: polls.objects.filter(id__gt=4).
    gte 大于等于.
    lt 小于.
    lte 小于等于.
    ne 不等于.
    in 位于给定列表中: polls.objects.filter(id__in=[1, 3, 4]) 返回一个 polls 列表(ID 值分别是 1或3或4).
    startswith 大小写敏感的 starts-with: polls.objects.filter(question__startswith="Would"). (仅PostgreSQL 和MySQL支持. SQLite 的LIKE 语句不支持大小写敏感特性. 对Sqlite 来说,``startswith`` 等于 istartswith)
    endswith 大小写敏感的 ends-with. (仅PostgreSQL 和 MySQL)
    istartswith 大小写不敏感的 starts-with.
    iendswith 大小写不敏感的 ends-with.
    range 范围测试: polls.objects.filter(pub_date__range=(start_date, end_date)) 返回 pub_date 位于 start_date 和 end_date (包括)之间的所有民意测验
    year 对 date/datetime 字段, 进行精确的  匹配: polls.get_count(pub_date__year=2005).
    month 对 date/datetime 字段, 进行精确的  匹配:
    day 对 date/datetime 字段, 进行精确的  匹配:
    isnull True/False; 做 IF NULL/IF NOT NULL 查询: polls.objects.filter(expire_date__isnull=True).
  • 相关阅读:
    编写代码的「八荣八耻」- 以用户易用为荣,以复杂歧义为耻
    《跃迁-成为高手的技术》之联机学习
    《跃迁-成为高手的技术》感悟
    JAVA SPI(Service Provider Interface)原理、设计及源码解析(其一)
    测试了一下编解码的执行效果
    谈面试中的亮点
    稳定性「三十六计」实战和背后的逻辑
    Python,Jupyter Notebook,IPython快速安装教程
    Python多进程编程
    R语言基础:数组&列表&向量&矩阵&因子&数据框
  • 原文地址:https://www.cnblogs.com/zhuzhiwei-2019/p/10869500.html
Copyright © 2011-2022 走看看