Reputation: 1655
Two models : Post and Author
This view displays the last Post for each Author (author is a ForeignKey)
I want to have these posts in a descending order, but it does not work.
The template keeps displaying these in a ascending way.
I try this following:
views.py
class LastestListView(ListView):
context_object_name = 'posts'
model = models.Post
ordering = ['-date']
paginate_by = 10
def get_queryset(self):
return self.model.objects.filter(pk__in=
Post.objects.values('author__id').annotate(
max_id=Max('id')).values('max_id'))
or:
class LastestListView(ListView):
context_object_name = 'posts'
model = models.Post
paginate_by = 10
def get_queryset(self):
return self.model.objects.filter(pk__in=
Post.objects.order_by('-date').values('author__id').annotate(
max_id=Max('id')).values('max_id'))
The ordering has to be set in the beginning of the Queryset:
class LastestListView(ListView):
context_object_name = 'posts'
model = models.Post
paginate_by = 10
def get_queryset(self):
return self.model.objects.order_by('-date').filter(pk__in=
Post.objects.values('author__id').annotate(
max_id=Max('id')).values('max_id'))
Upvotes: 4
Views: 3641
Reputation: 15568
It is more exact to say that the ordering should be applied to the main query, not to subquery.
I prefer the ordering after a filter, it is only a matter of opinion.
def get_queryset(self):
qs = (
self.model.objects
.filter(
pk__in=(
Post.objects
.values('author_id')
.annotate(max_id=Max('id'))
.values('max_id')
)
)
.order_by('-date')
)
# print(str(qs.query)) # SQL check is perfect for debugging
return qs
Maybe this more sparse style with strict indenting helps to write an easily readable code. The advantage is that you can easier comment out a method or change the order of methods by changing the order of lines. You can see also clearly if order_by
is in the main query or a subquery.
Upvotes: 5