【问题标题】:Django - querying objects via many-to-many relationDjango - 通过多对多关系查询对象
【发布时间】:2011-10-09 09:01:33
【问题描述】:

我的模型如下所示:

class Category(models.Model):
    name = models.CharField(_('name'), max_length=50)

class Product(models.Model):
    name = models.CharField(_('product name'), max_length=40)
    category = models.ManyToManyField(Category)

我正在尝试构建一个过滤查询,我可以在其中选择 1 个或多个类别并返回与所有选定类别相关的产品。

例子

Product_1 - 属于 category_1、category_2

Product_2 - 属于 category_1、category_2 和 category_3

在过滤 category_1 和 category_2 时,查询应返回这两个产品。在过滤所有 3 个类别时,只应返回 Product_2,因为这是与所有选定类别相关的唯一产品。

过滤将是动态的,因此要过滤的类别数量可能是无限的。

我该怎么做?我试过做

Product.objects.filter(category__in=[1,2,3])

但这给了我 product_1 和 product_2 因为它们匹配任何类别。

我尝试过创建 Q 过滤器

Product.objects.filter(Q(category__id=1), Q(category__id=2))

但这不会返回任何产品。

如何构造这样的查询来工作?

【问题讨论】:

    标签: django filter many-to-many


    【解决方案1】:

    我不知道一个简单的解决方案,但也许你可以使用这个解决方法:

    Product.objects.filter(category__in=[1,2,3]).annotate(total=Count('category')).filter(total=3)
    

    或者,您可以链接过滤器:

    Product.objects.filter(category=1).filter(category=2).filter(category=3)
    

    【讨论】:

    • 感谢您的回复。如何动态链接过滤器?
    • 好吧,您可以动态添加它们,例如在一个循环中,例如: qs = qs.filter(foo=bar)
    • 你可以使用reduce: queryset = reduce(lambda q, c: q.filter(category=c), [1,2,3], Product.objects.all())
    猜你喜欢
    • 2015-10-26
    • 1970-01-01
    • 2016-04-18
    • 2015-02-15
    • 1970-01-01
    • 2012-04-30
    • 1970-01-01
    • 2021-09-08
    • 2014-07-14
    相关资源
    最近更新 更多