Django orm跨多值关联,链式调用filter/exclude问题

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-31 03:46   129   0

跨多值关联

当基于 ManyToManyField 或反向 ForeignKey 筛选某对象时,设 Blog/Entry 关联关系(BlogEntry 是一种一对多关联关系)

Django 有一套统一的方式处理 filter() 调用。配置给某次 filter() 的所有条件会在调用时同时生效。


Filter

1.对于多值关联来说,限制条件作用于链接至主模型的对象,而不一定是那些被前置 filter() 调用筛选的对象

例如:

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

两段链式调用,都是作用域Blog模型,

第一个过滤器限制结果集为那些关联了标题包含 "Lennon" 的条目的博客。

第二个过滤器进一步要求结果集中的博客要发布于 2008 年。

第二个过滤器筛选的条目与第一个过滤器筛选的可能不尽相同。我们是用过滤器语句筛选 Blog,而不是 Entry

所以这条orm将筛选出包含 标题为"Lennon" 的博客条目发布于 2008 年的博客(并不是同时包含标题为Lennon 的博客和发布于 2008 年

2.那么要实现标题含有 标题为"Lennon" 且发布于 2008 (同一个条目,同时满足两个条件)年的博客

例如:

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

Exclude

1. filter() 的查询行为会跨越多值关联,就像前文说的那样,但 exclude() 不是这样。

例如:

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

查询出排除那些关联条目标题包含 "Lennon" 和同时满足有发布于 2008 年的博客

(只要多条数据中一条满足一个过滤条件即可,但必须是要有两种满足)

但并不会限制博客同时满足这两种条件NOT(id in A ∩ id in B)

2. 那么要满足 多条数据中一条满足一个过滤条件即可,但不必须是要有两种满足,实现如下:NOT id in A and NOT id in B

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

3. 那么要满足同时两种条件(在同一条目满足两个条件)实现如下:NOT (id in (A and B))

Blog.objects.exclude(
    entry__in=Entry.objects.filter(
        headline__contains='Lennon',
        pub_date__year=2008,
    ),
)

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP