【发布时间】:2020-01-24 21:25:51
【问题描述】:
我有类似于 Django 文档中的披萨示例的模型:
class Pizza(models.Model):
name = models.CharField()
toppings = models.ManyToManyField('Topping')
def __str__(self):
return self.name
class Topping(models.Model):
name = models.CharField()
def __str__(self):
return self.name
以及一些预期的比萨饼的浇头:
>>> pepperoni = Topping.objects.create(name='pepperoni')
>>> sausage = Topping.objects.create(name='sausage')
>>> pineapple = Topping.objects.create(name='pineapple')
>>> olives = Topping.objects.create(name='olives')
>>> p1 = Pizza.objects.create(name='Pepperoni')
>>> p1.toppings.add(pepperoni)
>>> p2 = Pizza.objects.create(name='Sausage')
>>> p2.toppings.add(sausage)
>>> p3 = Pizza.objects.create(name='Pepperoni and Sausage')
>>> p3.toppings.add(pepperoni)
>>> p3.toppings.add(sausage)
>>> p4 = Pizza.objects.create(name='Pepperoni and Olives')
>>> p4.toppings.add(pepperoni)
>>> p4.toppings.add(olives)
>>> p5 = Pizza.objects.create(name='Pepperoni and Sausage and Olives')
>>> p5.toppings.add(pepperoni)
>>> p5.toppings.add(sausage)
>>> p5.toppings.add(olives)
>>> ...
如何创建一个查询,只返回带有意大利辣香肠 (p1) 或香肠 (p2) 或两者都有意大利辣香肠或香肠 (p3) 的披萨?我不想要包含意大利辣香肠、香肠和其他东西的比萨 (p5)。
这样的东西包括一个有意大利辣香肠和橄榄的披萨 (p4),我不想要:
>>> Pizza.objects.filter(toppings__in=[pepperoni, sausage])
我可以创建一个除我想要的两个之外的所有浇头的列表并将其用作排除:
>>> toppings_i_do_not_want = Topping.objects.exclude(name__in=['Pepperoni', ['Sausage'])
>>> toppings_i_want = Topping.objects.filter(name__in=['Pepperoni', ['Sausage'])
>>> Pizza.objects.filter(toppings__in=toppings_i_want).exclude(toppings_i_do_not_want)
这将得到我想要的结果,但如果我只对两个浇头感兴趣,但我必须将大约 100,000 个其他浇头传递到排除过滤器中,这样的查询的性能似乎会受到很大影响。
有没有更好的办法?
【问题讨论】:
标签: django many-to-many django-queryset