Reputation: 2322
I have such model
class Product(models.Model):
created_at = models.DateTimeField(default=timezone.now)
cell = models.CharField(max_length=100, null=True)
Now I need a queryset that must be ordered by creation date and unique cell, something like Product.objects.order_by('created_at').distinct('cell')
but I got an sql error.
django.db.utils.ProgrammingError: SELECT DISTINCT ON expressions must match initial ORDER BY expressions
LINE 1: SELECT DISTINCT ON ("apps_product"."cell")
How should queryset be changed to get required result?
Upvotes: 0
Views: 237
Reputation: 1577
This is currently not possible without a Subquery. There is an open feature request that would allow queries like:
qs = (
Product.objects
# deduplicate on "cell", keeping the most recently created record
.order_by("cell", "-created_at").distinct("cell")
# then order the result of the distinct subquery to get most recently created first
.order_by("-created_at")
)
If you try this query now (as of Django 4.1.7), it will fail with the same error message you posted.
As a comment under the feature requests explains, you can try something like:
from django.db.models import Subquery
distinct = (
Product.objects
# deduplicate on "cell", keeping the most recently created record
.order_by("cell", "-created_at").distinct("cell")
.values("pk")
)
qs = (
Product.objects
.filter(pk__in=Subquery(distinct))
# then order the result of the distinct subquery to get most recently created first
.order_by("-created_at")
)
Upvotes: 0
Reputation: 1655
Folowing your error message, you should try:
Product.objects.order_by('cell', '-created_at').distinct('cell')
Upvotes: 2