使用 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 请求的记录的主要内容,如果未能解决你的问题,请参考以下文章