Reputation: 381
class Order(models.Model):
...
class OrderApplication(models.Model):
created_at = models.DateTimeField(auto_now=True)
driver = models.ForeignKey(Driver, on_delete=models.CASCADE)
suggested_price = models.DecimalField(..., blank=True, null=True)
I have the models as described above. All Orders usually have more than 1 OrderApplication (OA). However, there is only 1 OA for each Order which has a non-null suggested_price
field.
At some moments I have to serialize a list of Orders and send it to the front-end React app.
I want my orders to be placed in a very specific Order:
suggested_price
fieldcreated_at
fieldsuggested_price
and created as recently as possibleWhat I have already tried is ordering the Orders by the first created OA related to it:
.annotate(suggestion_created=Min('orderapplication__created_at')).order_by("-suggestion_created")
Here inside Min
aggregator I use a reversed foreign relation of the Order which is can be accessed as orderapplication
and get the first date of the objects which are in this reversed relation.
However, the problem is that it is not always true that the first OA related to any Order has suggested_price
specified (even though it's the most common case), it may be the 2nd, the 3rd or something else.
I have also tried using filter
parameter of the Min
, however, it turns out that this filter is applied to the Orders themselves, but not to the reversed relation.
What I see as a possible solution is to use some aggregation function which can filter reversed relation, however, I haven't found one
Upvotes: 1
Views: 322
Reputation: 476574
You can filter on the orderapplication
as well:
from django.db.models import Q
Order.objects.annotate(
suggestion_created=Min(
'orderapplication__created_at',
filter=Q(orderapplication__suggested_price__isnull=False)
)
).order_by('-suggestion_created')
Or you can simply put this in the .order_by
clause. If there is no such orderapplication
the value will be NULL
, you thus should decide if you want the NULL
s to be first or last:
from django.db.models import Q
Order.objects.order_by(
Min(
'orderapplication__created_at',
filter=Q(orderapplication__suggested_price__isnull=False)
).desc(nulls_last=True)
)
Upvotes: 2