1

有没有办法将未知数量的查询集连接到一个列表中?

这是我的模型:

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

我正在处理两种类型的查询:

  1. items = Item.objects.filter(brands__in=brands)

  2. items = Item.objects.filter(tags__name='80s').filter(tags__name='comedy')

对于第二种查询,用户可以保存搜索(例如“80年代喜剧”),并且可以同时保存多个搜索,所以我需要为他们保存的每个搜索创建一个查询。

我最初想尝试构建一个可以处理这两种情况的单个查询(请参阅Django Combining AND and OR Queries with ManyToMany Field),但我现在认为最好的方法是将所有查询组合到一个列表中。

我喜欢@akaihola 在这里建议的内容: 如何在 Django 视图中组合 2 个或更多查询集?但我不知道如何将 itertools.chain 与可变数量的查询一起使用。

有谁知道实现这一目标的最佳方法?

编辑:忘了提,我正在寻找的是具有特定品牌或具有所有必需标签的物品。

4

1 回答 1

3

有点不正统,但你可以使用递归。所以在你的例子中:

def recursive_search(tags, results_queryset):
    if len(tags) > 0:
        result_qs = result_queryset.filter(tags_name=tags[0])
        if result_queryset.exists():
            return filter_recursion(tags[1:],result_queryset)
        else:
            return None
    return result_queryset

tags = ["comedy", "80s", "action", "thriller"]  # This can be variable
result_queryset = Item.objects.filter(brands__in=brands) # Could be Item.objects.all()
print recursive_search(tags, result_queryset)

因此,您从要搜索的标签列表开始,以及可能符合您条件的所有商品的查询集(在这种情况下,我们从特定品牌的商品列表开始)

然后,您递归地逐个浏览标签列表并削减查询集。对于每个级别,您将整个查询集重新过滤为仅具有所有提到的标签的那些项目。

所以:

  • 第一个调用/级别将针对所有具有标签favorite的项目,
  • 第二个呼叫/级别将针对所有具有标签喜爱最响亮的项目,
  • 等等

如果过滤器返回的查询集是None,这意味着没有项目具有所有必需的标签,并且该方法将退出并返回None(即它在第一个可能的失败实例时退出)。此外,数据库应该只有一次点击(我认为!)

我已经对此进行了测试,它应该可以工作,所以试一试

编辑

要连接从品牌(q1)返回的查询集和上面使用 itertools(q2)创建的查询集:

list = []
for item in itertools.chain(q1, q2):
    list.append(item)

编辑 2

这不能在一个查询中完成您需要的吗?

# list of tags = ['comedy','80s']
qs = Item.objects.all( Q(brand__iexact="brand name") | Q(tags__name__in=[tag for tag in list_of_tags]) )
于 2011-06-04T00:28:12.620 回答