У меня есть модели, похожие на пример пиццы в документации 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 других начальных значений в фильтр исключения.
Есть ли лучший способ?