Skip to content

PaginatedListView changes and minor bug fix to an error message #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion class_based_views/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from class_based_views.base import View, TemplateView
from class_based_views.list import ListView, PaginatedListView
from class_based_views.list import ListView
from class_based_views.detail import DetailView
from class_based_views.dates import (ArchiveView, YearView, MonthView,
WeekView, DayView, TodayView,
Expand Down
2 changes: 1 addition & 1 deletion class_based_views/dates.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def get_dated_queryset(self, allow_future=False, **lookup):
qs = qs.filter(**{'%s__lte' % date_field: datetime.datetime.now()})

if not allow_empty and not qs:
raise Http404("No %s available" % qs.model._meta.verbose_name_plural)
raise Http404("No %s available" % unicode(qs.model._meta.verbose_name_plural))

return qs

Expand Down
85 changes: 40 additions & 45 deletions class_based_views/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class ListView(TemplateView):
allow_empty = True
template_object_name = None
queryset = None
paginate_by = None

def GET(self, request, *args, **kwargs):
queryset = self.get_queryset()
Expand All @@ -26,12 +27,21 @@ def get_context(self, queryset):
"""
Get the context for this view.
"""
context = {
'object_list': queryset,
}
context = {'object_list': queryset}
template_object_name = self.get_template_object_name(queryset)

if template_object_name is not None:
context[template_object_name] = queryset

if self.get_paginate_by(queryset):
page = self.kwargs.get('page', None)
paginator, page, queryset = self.paginate_queryset(queryset, page)
context.update({
'paginator': paginator,
'page_obj': page,
'is_paginated': paginator is not None,
})

return context

def get_queryset(self):
Expand All @@ -48,6 +58,32 @@ def get_queryset(self):
queryset = queryset._clone()
return queryset

def paginate_queryset(self, queryset, page):
"""
Paginate the queryset, if needed.
"""
paginate_by = self.get_paginate_by(queryset)
paginator = Paginator(queryset, paginate_by, allow_empty_first_page=self.get_allow_empty())
page = page or self.request.GET.get('page', 1)
try:
page_number = int(page)
except ValueError:
if page == 'last':
page_number = paginator.num_pages
else:
raise Http404("Page is not 'last', nor can it be converted to an int.")
try:
page = paginator.page(page_number)
return (paginator, page, page.object_list)
except InvalidPage:
raise Http404('Invalid page (%s)' % page_number)

def get_paginate_by(self, queryset):
"""
Get the number of items to paginate by, or ``None`` for no pagination.
"""
return self.paginate_by

def get_allow_empty(self):
"""
Returns ``True`` if the view should display empty lists, and ``False``
Expand Down Expand Up @@ -82,45 +118,4 @@ def get_template_object_name(self, queryset):
return smart_str(queryset.model._meta.verbose_name_plural)
else:
return None


class PaginatedListView(ListView):
paginate_by = None

def get_context(self, queryset):
page = self.kwargs.get('page', None)
paginator, page, queryset = self.paginate_queryset(queryset, page)
context = super(PaginatedListView, self).get_context(queryset)
context.update({
'paginator': paginator,
'page_obj': page,
'is_paginated': paginator is not None,
})
return context

def paginate_queryset(self, queryset, page):
"""
Paginate the queryset, if needed.
"""
paginate_by = self.get_paginate_by(queryset)
paginator = Paginator(queryset, paginate_by, allow_empty_first_page=self.get_allow_empty())
page = page or self.request.GET.get('page', 1)
try:
page_number = int(page)
except ValueError:
if page == 'last':
page_number = paginator.num_pages
else:
raise Http404("Page is not 'last', nor can it be converted to an int.")
try:
page = paginator.page(page_number)
return (paginator, page, page.object_list)
except InvalidPage:
raise Http404('Invalid page (%s)' % page_number)

def get_paginate_by(self, queryset):
"""
Get the number of items to paginate by, or ``None`` for no pagination.
"""
return self.paginate_by


3 changes: 2 additions & 1 deletion class_based_views/tests/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ class AuthorList(class_based_views.ListView):
template_name = 'tests/list.html'


class PaginatedAuthorList(class_based_views.PaginatedListView):
class PaginatedAuthorList(class_based_views.ListView):
queryset = Author.objects.all()
template_name = 'tests/list.html'
paginate_by = 5


class AuthorCreate(class_based_views.CreateView):
Expand Down