Reputation: 295
Django: order by multi-level reverse look up
I have following 3 models
class Product(models.Model):
name = models.CharField(
blank=False,
max_length=256
)
class TaskGroup(models.Model):
name = models.CharField(
blank=False,
max_length=256
)
product = models.ForeignKey(
Product,
on_delete=models.CASCADE,
null=False,
blank=True
)
class Task(models.Model):
name = models.CharField(
blank=False,
max_length=256
)
task_group = models.ForeignKey(
TaskGroup,
on_delete=models.CASCADE,
null=False,
blank=True
)
execute_at = models.DateField(
blank=True
null=True,
)
I want to get all the Products
ordered by the execute_at
date of Task
. How can I do this?
Is it possible to do this using a single query?
There can be multiple tasks for a product. But always consider the smaller execute_at
date i.e
the date that is closest to current date.
Upvotes: 1
Views: 141
Reputation: 476534
You can .annotate(…)
[Django-doc] by the maximum of the created_at
field, and then order with:
from django.db.models import Max
Products.objects.annotate(
last_task=Max('taskgroup__task__execute_at')
).order_by('-last_task')
You can order items with no related Task
at the end with:
from django.db.models import F, Max
Products.objects.annotate(
last_task=Max('taskgroup__task__execute_at')
).order_by(F('last_task').desc(nulls_last=True))
Upvotes: 3