简体   繁体   中英

Django sort queryset by related model field

I have the following models (abbreviated for clarity):

class Order(models.Model):
    some fields

class OrderStatus(models.Model):
    order = models.ForiegnKey(Order)
    status = models.CharField(choices=['ORDERED', 'IN_TRANSIT', 'RECEIVED'])
    time = models.DateTimeField()

I would like to sort all Orders that contain all three OrderStatuses by their order received time.

In other words, select the orders that have records of Ordered, In Transit, and Received like so:

Order.objects.filter(orderstatus__status=OrderStatus.ORDERED)
             .filter(orderstatus__status=OrderStatus.IN_TRANSIT)
             .filter(orderstatus__status=OrderStatus.RECEIVED)

... and then sort them by the time field of their related OrderStatus model for which status=OrderStatus.RECEIVED .

This is where I'm stuck. I have read the Django docs on the .extra() queryset modifier and direct SQL injection, but I'm still at a loss. Could I achieve it with an annotated field and Q objects or am I better going the .extra route?

Didn't you try to do like this?

Order.objects.filter(orderstatus__status=OrderStatus.ORDERED)
             .filter(orderstatus__status=OrderStatus.IN_TRANSIT)
             .filter(orderstatus__status=OrderStatus.RECEIVED)
             .order_by('orderstatus__time')

On my models it worked as expected - order_by picked the last joined orderstatus just as you need. If you're not sure you can check the real query like this (in django shell):

from django.db import connection
# perform query
print(connection.queries)

Also it can be done like this:

OrderStatus.objects.filter(status=OrderStatus.RECEIVED)
                   .order_by('time').select_related('order')
                   .filter(order__orderstatus__status=OrderStatus.ORDERED)
                   .filter(order__orderstatus__status=OrderStatus.IN_TRANSIT)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM