在Django中通过反向存在检查过滤查询集

Posted

技术标签:

【中文标题】在Django中通过反向存在检查过滤查询集【英文标题】:Filter queryset by reverse exists check in Django 【发布时间】:2015-08-18 09:08:23 【问题描述】:

我有模型:

class Post(models.Model):
    content = models.CharField()
    user = models.ForeignKey('users.User')
    active = models.BooleanField(default=True)

class Comment(models.Model):
    post = models.ForeignKey(Post, related_name='post_comments')

还有一个由查询参数过滤的查询集:

user = request.QUERY_PARAMS.get('user_id', None)
active = request.QUERY_PARAMS.get('active', None)
has_comments = request.QUERY_PARAMS.get('has_comments', None)

qs = Post.objects.all()

if user:
    qs = qs.filter(user=user)
if active:
    qs = qs.filter(active=active)
if has_comments:
    ???

我不明白如何在保留所有先前过滤器的同时过滤此查询。有可能吗?

【问题讨论】:

【参考方案1】:

根据documentation:

要引用“反向”关系,只需使用模型的小写名称即可。

来自this answer,您的代码将是:

if user:
    qs = qs.filter(user=user)
if active:
    qs = qs.filter(active=active)
if has_comments:
    qs = qs.filter(comment__isnull=False)

关于性能,请考虑this answer:

Django 不支持反向外部的 select_related() 方法 键查找,所以你可以在不离开 Python 的情况下做的最好的事情是两个 数据库查询。

您还应该看看prefetch_related,它与select_related 不同,它可以通过反向ForeignKeys 进行查找,尽管对查询集的每个元素都有单独的查询。

【讨论】:

谢谢! qs.filter(post_comments__isnull=False) 有效。在文档中对此进行更多解释会很好。 请注意,我的博客条目已经过时了,当我写这篇文章时还没有添加 prefetch_related ,它和我在那里所说的差不多。

以上是关于在Django中通过反向存在检查过滤查询集的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法检查字符串是不是是 django 查询集的有效过滤器?

如果字段存在,Django过滤查询集

包含列表中所有值的 Django 反向查询集

在xcode中通过sqlite3检查存在

如何通过django中的多级反向外键获取相关对象查询集?

django 设计模式/最佳实践:过滤查询集