It all started with me trying to apply slices to a queryset to limit it. As I understand the documentation it is supposed to limit the results to 10 entries:
def get_queryset(self, *args, **kwargs):
qs = Message.objects.all()
qs = qs.filter(Target_id=self.dialog)[:10] # here the limit
qs = qs.annotate(sender_id=Max('Sender__id'))
return qs
But really in template the request returns me all the records, but applies the annotation only to the first 10. I do not know why.
I thought the whole reason was annotate.
Then I remove the last line (with annotate). However I got in the template all the records instead of 10. That is same result as if I didn't make the slice.
In my template I'm not doing anything unusual: the iteration over the my queryset:
{% for message in messages %}
{{message}}
{% endfor %}
This is weird: if I take len(qs)
in my view, I get 10! But in template I get 300! It doesn't fit in my head.
I tried also to apply slice in the template instead of my view:
{% for message in messages|slice:":10" %}
But nothing has changed.
I have got all messages in my template instead of 10. How could this be?
PS: database type is sqlite.
It is documented that it is not advisable to futher modify a queryset after slicing [Django-doc]:
Also note that even though slicing an unevaluated
QuerySet
returns another unevaluatedQuerySet
, modifying it further (e.g., adding more filters, or modifying ordering) is not allowed, since that does not translate well into SQL and it would not have a clear meaning either.
You should change the order, like:
def get_queryset(self, *args, **kwargs):
return Message.objects.filter(Target_id=self.dialog).annotate(
sender_id=Max('Sender__id')
)[:10]
So you first .filter(…)
[Django-doc]/.annotate(…)
[Django-doc], and then you slice.