如何使用 Django 执行 __all_in 查询?
How to perform a __all_in query with Django?
我有三个模型
class Pizza(models.Model):
toppings = models.ManyToManyField(Topping)
class Topping(models.Model):
name = models.CharField(max_length=50)
class Order(models.Model):
must_have_toppings = models.ManyToManyField(Topping)
我想找到与特定披萨匹配的所有订单。
为此,我想做一些像
orders = Order.objects.filter(must_have_toppings__all_in=my_pizza.toppings)
我尝试了什么:
orders = Order.objects.filter(must_have_toppings__in=my_pizza.toppings)
不起作用,因为 must_have 中只有一种披萨配料的订单将被 returned。
并且:
orders = Orders.objects
for topping in my_pizza.toppings.all():
orders = orders.filter(must_have_toppings=topping)
不起作用,因为它将 return 包含比萨所有配料的订单,即使某些 must_have_toppings
缺失。例如,西红柿和蘑菇比萨将 return 需要西红柿、胡椒和蘑菇的订单。
如何查找 must_have_toppings 都在 Pizza 对象中的订单?
(我正在使用 MySql)
如果您想查找订单中所有 Topping
都属于 my_pizza
的订单,我们可以过滤:
from django.db.models import F, Q
toppings = my_pizza.toppings.all()
Order.objects.annotate(
ntoppings=Count(
'must_have_toppings',
<strong>filter=Q(must_have_toppings__in=toppings)</strong>
),
total=Count('must_have_toppings')
).filter(
ntoppings=F('total')
)
我们这里先获取my_pizza
的所有toppings,然后检查toppings的数量i是否与属于my_pizza
的toppings的数量相同,如果成立,我们知道订单的所有浇头都是该披萨的成员。
我们也可以反其道而行之,检查 my_pizza
的所有浇头是否都属于 Order
:
from django.db.models import Count, Q
toppings = my_pizza.toppings.all()
ntoppings = len(toppings)
Order.objects.annotate(
ntoppings=Count(
'must_have_toppings',
<strong>filter=Q(must_have_toppings__in=toppings)</strong>
)
).filter(
ntoppings=ntoppings
)
如果 Order
的配料比比萨多,则该订单仍会显示。因此,如果比萨有奶酪和菠萝作为配料,那么奶酪、萨拉米香肠和菠萝的订单会匹配。
对于订单和 my_pizza
具有完全相同浇头的完全匹配,我们可以使用:
from django.db.models import Count, Q
toppings = my_pizza.toppings.all()
ntoppings = len(toppings)
Order.objects.annotate(
ntoppings=Count(
'must_have_toppings',
<strong>filter=Q(must_have_toppings__in=toppings)</strong>
),
total=Count('must_have_toppings')
).filter(
ntoppings=ntoppings,
total=ntoppings
)
所有代码片段都假定浇头只能发生一次。
我有三个模型
class Pizza(models.Model):
toppings = models.ManyToManyField(Topping)
class Topping(models.Model):
name = models.CharField(max_length=50)
class Order(models.Model):
must_have_toppings = models.ManyToManyField(Topping)
我想找到与特定披萨匹配的所有订单。 为此,我想做一些像
orders = Order.objects.filter(must_have_toppings__all_in=my_pizza.toppings)
我尝试了什么:
orders = Order.objects.filter(must_have_toppings__in=my_pizza.toppings)
不起作用,因为 must_have 中只有一种披萨配料的订单将被 returned。
并且:
orders = Orders.objects
for topping in my_pizza.toppings.all():
orders = orders.filter(must_have_toppings=topping)
不起作用,因为它将 return 包含比萨所有配料的订单,即使某些 must_have_toppings
缺失。例如,西红柿和蘑菇比萨将 return 需要西红柿、胡椒和蘑菇的订单。
如何查找 must_have_toppings 都在 Pizza 对象中的订单?
(我正在使用 MySql)
如果您想查找订单中所有 Topping
都属于 my_pizza
的订单,我们可以过滤:
from django.db.models import F, Q
toppings = my_pizza.toppings.all()
Order.objects.annotate(
ntoppings=Count(
'must_have_toppings',
<strong>filter=Q(must_have_toppings__in=toppings)</strong>
),
total=Count('must_have_toppings')
).filter(
ntoppings=F('total')
)
我们这里先获取my_pizza
的所有toppings,然后检查toppings的数量i是否与属于my_pizza
的toppings的数量相同,如果成立,我们知道订单的所有浇头都是该披萨的成员。
我们也可以反其道而行之,检查 my_pizza
的所有浇头是否都属于 Order
:
from django.db.models import Count, Q
toppings = my_pizza.toppings.all()
ntoppings = len(toppings)
Order.objects.annotate(
ntoppings=Count(
'must_have_toppings',
<strong>filter=Q(must_have_toppings__in=toppings)</strong>
)
).filter(
ntoppings=ntoppings
)
如果 Order
的配料比比萨多,则该订单仍会显示。因此,如果比萨有奶酪和菠萝作为配料,那么奶酪、萨拉米香肠和菠萝的订单会匹配。
对于订单和 my_pizza
具有完全相同浇头的完全匹配,我们可以使用:
from django.db.models import Count, Q
toppings = my_pizza.toppings.all()
ntoppings = len(toppings)
Order.objects.annotate(
ntoppings=Count(
'must_have_toppings',
<strong>filter=Q(must_have_toppings__in=toppings)</strong>
),
total=Count('must_have_toppings')
).filter(
ntoppings=ntoppings,
total=ntoppings
)
所有代码片段都假定浇头只能发生一次。