Django 在两个表上使用与预取相关的两个筛选器

Django 在两个表上使用与预取相关的两个筛选器,django,django-models,django-views,django-queryset,Django,Django Models,Django Views,Django Queryset,假设这是我的模型: class Pizza(models.Model): size = models.IntegerField() #other fields class Order(models.Model): date = models.DateField() pizza = models.ManyToManyField(Pizza, through='OrderPizza') #other fields class OrderPizza(mod

假设这是我的模型:

class Pizza(models.Model):
    size = models.IntegerField()
    #other fields

class Order(models.Model):
    date = models.DateField()
    pizza = models.ManyToManyField(Pizza, through='OrderPizza')
    #other fields


class OrderPizza(models.Model):
    update = models.BooleanField()
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    pizza = models.ForeignKey(Pizza, on_delete=models.CASCADE)
我试着在最后一次订单中查看32号比萨饼的id如何仅使用一个查询集即可完成此操作?

#I take the last order:
last_order =  Orders.objects.filter().order_by('-order_number')[:1]

#If we have at least one order
if last_order:
    var_last_order_id = last_order[0].id
    #First filter
    queryset_orders = Orders.objects.filter(id=var_last_order_id).prefetch_related('pizza')

    for food in queryset_orders:
        #Second filter
        pizza32 = food.pizza.filter(size = 32)
        print pizza32.id

我可能误解了你的要求,但听起来你可以:

if Order.objects.exists():
    last_order = Order.objects.order_by('-order_number')[:1]
    pizza32 = last_order.pizza.filter(size=32)

您在
queryset\u orders
上的循环是不必要的,因为
last\u order
已经是最新的订单。

您可以通过以下方式获得比萨饼大小为32的订单:

orders = Orders.objects.filter(pizza__size=32)
您可以通过以下方式获得这些订单中的最后一个:

last_order = Orders.objects.filter(
    pizza__size=32,
).order_by('-order_number')[0]
使用
prefetch\u related
,您可以在同一查询中获取比萨饼:

last_order = Orders.objects.filter(
    pizza__size=32,
).order_by('-order_number').prefetch_related('pizza')[0]
现在,当您执行
last\u order.pizza.all()
时,将不会有任何额外的SQL查询。如果您知道订单中只有一个比萨饼,您可以:

for pizza in last_order.pizza.all():
    pizza
pizza32 = Pizza.objects.filter(order=last_order, size=32)
或者从订单中获得第一份比萨饼:

last_order.pizza.all()[0]

我也不太确定您希望删除代码的哪一部分。 如果您已经检索到上一个订单,则可以执行以下操作:

for pizza in last_order.pizza.all():
    pizza
pizza32 = Pizza.objects.filter(order=last_order, size=32)
当然,这会给你一个比萨饼查询集,所以你不能做
pizza32.id

如果您只想要比萨饼,而不事先检索订单,则可以加入查询。这将创建在一条SQL语句中执行的查询:

pizza32 = Pizza.objects.filter(order__in=Order.objects.order_by('-order_number')[:1], size=32)

我只想创建一个查询,而不是queryset\u orders=orders.objects.filter(id=var\u last\u order\u id)。prefetch\u related('pizza')和pizza32=food.pizza.filter(size=32)。你认为这可能吗?我不认为你可以。在一个查询中这样做有什么意义?