Django 组合可变数量的查询集
有没有办法将未知数量的查询集连接到一个列表中?
这是我的模型:
class Item(models.Model):
name = models.CharField(max_length=200)
brand = models.ForeignKey(User, related_name='brand')
tags = models.ManyToManyField(Tag, blank=True, null=True)
def __unicode__(self):
return self.name
class Meta:
ordering = ['-id']
class Tag(models.Model):
name = models.CharField(max_length=64, unique=True)
def __unicode__(self):
return self.name
我正在处理两种类型的查询:
items = Item.objects.filter(brands__in=brands)
- < p>items = Item.objects.filter(tags__name='80s').filter(tags__name='comedy')
对于第二种查询,用户可以保存搜索(例如“80s喜剧”),并且可以在同时,所以我需要为他们保存的每个搜索创建一个查询。
我最初想尝试构建一个可以处理这两种情况的单个查询(请参阅 Django 将 AND 和 OR 查询与 ManyToMany 字段组合 ),但我现在认为最好的方法是将所有查询合并到一个列表中。
我喜欢@akaihola 在这里的建议: 如何组合 2 个或多个Django 视图中的查询集? 但我不知道如何将 itertools.chain 与可变数量的查询一起使用。
有谁知道实现这一目标的最佳方法?
编辑:忘了提及,我正在寻找的是具有特定品牌或具有所有必需标签的物品。
Is there a way to concatenate a unknown number of querysets into a list?
Here are my models:
class Item(models.Model):
name = models.CharField(max_length=200)
brand = models.ForeignKey(User, related_name='brand')
tags = models.ManyToManyField(Tag, blank=True, null=True)
def __unicode__(self):
return self.name
class Meta:
ordering = ['-id']
class Tag(models.Model):
name = models.CharField(max_length=64, unique=True)
def __unicode__(self):
return self.name
I have two types of queries that I'm working with:
items = Item.objects.filter(brands__in=brands)
items = Item.objects.filter(tags__name='80s').filter(tags__name='comedy')
With regards to the second type of query, users can save searches (for example "80s comedy"), and can save multiple searches at the same time, so I will need to create a query for each search that they have saved.
I originally wanted to try and construct a single query that will handle both cases (see Django Combining AND and OR Queries with ManyToMany Field ), but I now think the best way to do this would be to combine all queries into a list.
I like what @akaihola suggests here:
How to combine 2 or more querysets in a Django view? but I can't figure out how to use itertools.chain with a variable number of queries.
Does anyone know the best way to accomplish that?
EDIT: Forgot to mention, what I'm looking for are items that have a certain brand OR have all of the required tags.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有点不正统,但你可以使用递归。因此,在您的示例中:
因此,您从要搜索的标签列表以及可能符合您条件的所有商品的查询集开始(在本例中,我们从特定品牌的商品列表开始)
然后,您将一一递归地浏览标签列表并缩减查询集。对于每个级别,您将整个查询集重新过滤为仅包含所有提到的标签的项目。
所以:
如果过滤器返回的queryset为None,则表示不存在包含所有所需标签的项目,该方法将退出并返回None(即在第一个可能的情况下退出)失败的实例)。此外,应该只对数据库进行一次点击(我认为!)
我已经对此进行了测试,它应该可以工作,所以尝试一下
编辑
来连接从品牌返回的查询集( q1) 和上面使用 itertools (q2) 创建的查询集:
编辑 2
这是否无法在一个查询中实现您所需的功能?
Slightly unorthodox, but you could use recursion. So in your example:
So you start off with a list of the tags you are searching for, and a queryset of ALL of your items that could possibly fit your criteria (in this case we start with the list of items of a particular brand)
You then recursively go through the list of tags one by one and cut the queryset down. For each level, you re-filter the entire queryset to only those items which have all the mentioned tags.
so:
If the queryset returned by the filter is None, it means there are no items that have all the required tags, and the method will quit and return None (i.e. it quits at the first possible instance of failure). Furthermore, there should only be a single hit to the database (I think!)
I've tested this out and it should work, so give it a shot
EDIT
To concatonate the queryset returned from the brands (q1) and the queryset created above using itertools (q2):
EDIT 2
does this not accomplish what you need in one query?