Models and Databases 2.Making queries

save

关系字段

更新时放入所指向的model实例,如果是多对多要用add方法
可以直接传入id

Entry.objects.filter(blog=b) # Query using object instance
Entry.objects.filter(blog=b.id) # Query using id from instance
Entry.objects.filter(blog=5) # Query using id directly

对于普通的id也能查询,可使用

Entry.objects.filter(blog_id=4)

retrieve

默认使用的Manager是objects
XXModel.objects.all()

链式使用filter和exclude

因为使用了filter和exclude之后的结果也是QuerySet所以可以链式使用

>>> Entry.objects.filter(
...     headline__startswith='What'
... ).exclude(
...     pub_date__gte=datetime.date.today()
... ).filter(
...     pub_date__gte=datetime.date(2005, 1, 30)
... )

使用get获取单一的对象

其他的方法

limit

lookuptype

默认是exact完全匹配
iexact会忽略大小写
contains包含
icontains忽略大小写的包含
startswith endswith istartswith iendswith
如果想过滤关联的内容,可直接使用,反向的也行

关系查询

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

如果查询时Blog中没有对应的entry,理论上这里的authors为None,应该报错,但是django处理后返回为空,视为未查询到,但是在使用isnull时会出问题

Blog.objects.filter(entry__authors__name__isnull=True)

这样会查询出name为空的和authors为空的,可用

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

先确保authors存在,再查询name为空的

关于多值的关系

注意filter和exclude都是在本model上的操作,限制的结果也是本model

Blog.objects.filter(entry__headline__contains='Lennon', entry__pub_date__year=2008)
# 同时满足这两个筛选项
Blog.objects.filter(entry__headline__contains='Lennon').filter(entry__pub_date__year=2008)
# 这里对于本model的查询应该是一致的(例如上面的链式),但是这里使用了两步,那么
# 每次的entry都是该Blog所对应的全部entry而未加限制

行内比较使用F表达式

Entry.objects.filter(n_comments__gt=F('n_pingbacks'))
n_comments__gt=F('n_pingbacks') * 2
rating__lt=F('n_comments') + F('n_pingbacks')
>>> Entry.objects.filter(authors__name=F('blog__name'))
mod_date__gt=F('pub_date') + timedelta(days=3)

PK

pk=14
pk__in=[1, 2]
pk__gt=14

使用%的转置方式

cache

没有完整遍历过的queryset不会缓存

for in
bool转换 list转换

Q

把上述的过滤语句包装为整体,可用& | ~连接来形成 且 或 非 操作

comparing

使用主键

del

可在单独的object上调用delete,也可在queryset上调用delete

copy

设置主键为None再保存,但不会自动处理关系字段

如果涉及到了继承,那么需要将pk id都设置

复制后不会自动设置例如多对多关系的成员,另外一对一的字段应该预先复制好

多行更新

update可以批量修改本model的字段和外键
使用的直接是update语句,所以不会调用save,所以pre_save post_save的信号也不会触发,auto_now的选项也不会遵循,

Related Objects

多对一 ForeignKey

例如一个Entry可用用e.blog来获得Blog,Blog可用b.entry_set.all()来反向获得Entry的列表
在创建ForeignKey时指定了related_name来设置默认的entry_set名字,例如设置为entries,则可用entries.all()来反向获得Entry的列表
默认使用的Manger也是default manager的子类,如果在entry中设置了自定义的manager,可在获取时使用b.entry_set(manager='entries').all(),通过manger参数来指定,这样可调用自定义manger中的方法
对于反向的manager,可用add create remove clear set

多对多 ManyToManyField

定义了ManyToManyField字段的model中使用定义的字段名称,而反向的model中还是使用_set的方式,同样可用related_name来指定

一对一 OneToOneField

注意自动生成的反向名称是model名称,例如Blog使用entry,Entry中使用blog

如何实现的

利用了app registry,引入INSTALLED_APPS中的app和model,

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 原文:https://my.oschina.net/liuyuantao/blog/751438 查询集API 参...
    阳光小镇少爷阅读 3,854评论 0 8
  • Django 1.8.2 文档Home | Table of contents | Index | Modules...
    轩辕小爱阅读 2,384评论 0 2
  • __exact 精确等于 like 'aaa'__iexact 精确等于 忽略大小写 ilike'aaa'...
    amazing_bing阅读 728评论 0 0
  • 查询条件: exact:在底层会被翻译成=。 iexact:在底层会被翻译成LIKE。LIKE和=:大部分情况下都...
    xinmin阅读 570评论 0 0
  • 定义类属性 Django会自动创建自动增长的主键字段每个模型只能有一个主键如果使用选项设置某属性为主键字段后dja...
    sophia4syn阅读 599评论 0 1