使用 django-taggits 过滤带有 AND 请求的记录

Posted

技术标签:

【中文标题】使用 django-taggits 过滤带有 AND 请求的记录【英文标题】:Filtering records with AND requests with django-taggits 【发布时间】:2016-10-11 03:33:18 【问题描述】:

我正在尝试使用以下代码查找同时具有两个标签的记录:

values = s.split(',')

query = Q()

for item in values:
    query &= Q(tags__name__iexact=item.strip())

photos = Photo.objects.filter(query).distinct();

返回空查询集。 Django-taggit 文档仅提供此示例

 Food.objects.filter(tags__name__in=["delicious"])

返回所有包含 any 标签的记录,但不能同时返回两个

更新

这就是我在代码中使用“过滤器链接”的方式。

photos = Photo.objects
for value in values:
    photos = photos.filter(tags__name__icontains=value.strip())

实际上是什么意思

photos.filter(...).filter(...).filter(...)...

这可能是超慢的,但对我有用。

【问题讨论】:

可以发一下照片查询(print(photos.query))吗? @ElwinArens 这里是一个例子:pastebin.com/3PFivTqr 【参考方案1】:

我不知道这是否是最好的方法,但这绝对是一种简单的方法:-)

values = s.split(',')
sets = [];

# first get a list of sets of photos containing one tag at a time
for tag in values:
    sets.append(set(Photo.objects.filter(tags__name__in=[tag])))

# now intersect all sets to get only photos with all tags
photos = set.intersection(*sets)

【讨论】:

我不太确定它不是超级慢,尤其是在请求很大的情况下。这就是我最后的做法(添加到原帖中) 好吧,对于大量的值,它肯定会变得非常慢,因为它会针对每个值访问数据库。链接过滤器绝对是一种更好的方法,因为生成的 SQL 只会访问数据库一次......并且可能最终得到一个 AND 语句,这正是您真正想要的。感谢分享。 ...您应该将更新后的代码作为答案,因为这是您问题的一个很好的答案。 ...关于性能,这里有一个关于链接过滤器的好问题:***.com/q/11026401/466275 ...我错了,它不只是以 AND 查询结束。刚刚使用print Photo.objects....filter(...).filter(...).query 进行了测试,生成的 SQL 看起来非常复杂,有很多 INNER JOINS……但最后它比多次访问数据库要好得多:-)

以上是关于使用 django-taggits 过滤带有 AND 请求的记录的主要内容,如果未能解决你的问题,请参考以下文章

无法使用存储过程过滤带有 % mysql 的行

R如何使用带有过滤器或过滤器_的卷曲卷曲?

使用游标适配器实现带有过滤器的多选列表视图

带有特殊字符的 NSPredicate 过滤

使用带有数据数组的 Yii2 和带有排序和过滤的 Gridview

使用带有网络过滤器的漂亮面孔