Pagination works ok until I add reverse
arg to QS for ordering queryset in reverse mode. After it pagination is broke. I can use get()
function and paginate it there, but I think that for this issue should be better solution. Thanks
model.py:
class Log(models.Model):
user = models.ForeignKey('auth.User')
comment = models.CharField()
date_add = models.DateTimeField()
class Meta:
ordering = ['-date_add']
view.py:
class LogView(ListView):
model = UserLog
template_name = 'log.html'
context_object_name = 'log_list'
paginate_by = 13
def get_queryset(self):
return Log.objects.filter(user=self.request.user).all()
def get_context_data(self, *, object_list=None, **kwargs):
context = super(LogView, self).get_context_data(**kwargs)
if 'reverse' in self.request.GET:
context['log_list'] = Log.objects.filter(user=self.request.user).all().order_by('date_add')
return context
Move the code that runs the queryset to get_queryset
, so that it runs before the queryset is paginated.
def get_queryset(self):
queryset = Log.objects.filter(user=self.request.user).all()
if 'reverse' in self.request.GET:
queryset = queryset.order_by('date_add')
return queryset
The pagination is called in the get_context_data
of the MultipleObjectMixin
[GitHub] :
def get_context_data(self, *, object_list=None, **kwargs): """Get the context for this view.""" queryset = object_list if object_list is not None else self.object_list page_size = self.get_paginate_by(queryset) context_object_name = self.get_context_object_name(queryset) if page_size: paginator, page, queryset, is_paginated = self.paginate_queryset(queryset, page_size) context = { 'paginator': paginator, 'page_obj': page, 'is_paginated': is_paginated, 'object_list': queryset } else: context = { 'paginator': None, 'page_obj': None, 'is_paginated': False, 'object_list': queryset } if context_object_name is not None: context[context_object_name] = queryset context.update(kwargs) return super().get_context_data(**context)
By overriding the element of the dictionary, you thus bypass this pagination.
I think it is however better in this use-case to transfer the logic to the get_queryset
method, in that case, you even do not have to override the get_context_data
:
class LogView(ListView):
model = UserLog
template_name = 'log.html'
context_object_name = 'log_list'
paginate_by = 13
def get_queryset(self):
if :
return Log.objects.filter(user=self.request.user).all().order_by('date_add')
else:
return Log.objects.filter(user=self.request.user).all()
Note that the above has two potential problems:
'reverse'
is not in self.request.GET
, which means that - unless you order in the model - there is no order, and hence pagination might go wrong over multiple pages; page
key in request.GET
, this can result in some trouble in the links that change the GET parameter, since if you specify an url with ?page=3
, the reverse
key will get dropped.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.