django - 通过 ManyToMany 字段过滤

时间:2021-03-09 11:42:37

标签: python django

假设我有这样的模型:

class Pizza(models.Model):
    name = models.CharField(max_length=100)


class Topping(models.Model):
    name = models.CharField(max_length=100)


class Flavor(models.Model):
    name = models.CharField(max_length=100)
    of_topping = models.ForeignKey(Topping, on_delete=models.CASCADE)
    on_pizzas = models.ManyToManyField(Pizza)

然后,我有“辣味”、“非辣味”和“意大利”口味的“意大利腊肠”浇头,以及“香菇”、“牛肝菌”和“木耳”口味的浇头“真菌”。

一个比萨饼被限制为不能包含两个相同 Topping 类别但口味不同的浇头。 (例如,没有意大利腊肠和辣味意大利腊肠的比萨)。

现在,假设我的披萨店提供这些披萨:

  • 玛格丽特(无浇头)
  • Salami(不辣的意大利腊肠)
  • Funghi(香菇)
  • 美味(意大利腊肠和香菇)
  • 有毒(辣意大利腊肠和飞木耳)
  • 特制(意大利腊肠和牛肝菌)

现在,对于客户 Bob,我知道是约束,例如他会吃香菇和意大利腊肠(但也会吃任何只有其中一部分作为浇头的东西)。 对于 Bob,我不想知道我可以给他提供 Margherita、Funghi 或 Yummy。 对于每个客户,约束列表将只包括(最多)每个浇头的一种口味。所以不会有顾客说她既喜欢辣又喜欢不辣的意大利腊肠。

如何编写执行此操作的过滤器?类似的东西

Pizza.objects.filter(flavor__??=list_of_flavor_constraints)

1 个答案:

答案 0 :(得分:0)

您的查询对于单个查询来说过于复杂。它要么需要多个连接,要么需要一个子查询。我还没有测试过这个,但试试这个:

from django.db.models import Subquery

excluded_pizzas = Flavor.on_pizzas.through.objects.exclude(flavor__in=list_of_flavor_constraints).values('pizza')
result = Pizza.objects.exclude(id__in=Subquery(excluded_pizzas))

excluded_pizzas 是在中间 m2m 表上执行的子查询,我们在其中排除用户实际想要的口味并选择比萨的 id,为我们提供我们实际上不想要的比萨.

接下来,我们实际上排除了这些比萨的 ID,从而为我们提供了我们想要的比萨。

相关问题