Fixed #3542 -- Add support for changing granularity on ArchiveView.

Resolving the concept from a very old ticket in a more class-based-view
manner.
This commit is contained in:
Marc Tamlyn 2012-08-18 16:28:17 +01:00
parent de3ad8bb2d
commit 8d5c11caad
4 changed files with 23 additions and 5 deletions

View File

@ -327,6 +327,7 @@ class BaseDateListView(MultipleObjectMixin, DateMixin, View):
Abstract base class for date-based views displaying a list of objects. Abstract base class for date-based views displaying a list of objects.
""" """
allow_empty = False allow_empty = False
date_list_period = 'year'
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.date_list, self.object_list, extra_context = self.get_dated_items() self.date_list, self.object_list, extra_context = self.get_dated_items()
@ -370,13 +371,18 @@ class BaseDateListView(MultipleObjectMixin, DateMixin, View):
return qs return qs
def get_date_list(self, queryset, date_type): def get_date_list_period(self):
return self.date_list_period
def get_date_list(self, queryset, date_type=None):
""" """
Get a date list by calling `queryset.dates()`, checking along the way Get a date list by calling `queryset.dates()`, checking along the way
for empty lists that aren't allowed. for empty lists that aren't allowed.
""" """
date_field = self.get_date_field() date_field = self.get_date_field()
allow_empty = self.get_allow_empty() allow_empty = self.get_allow_empty()
if date_type is None:
date_type = self.get_date_list_period()
date_list = queryset.dates(date_field, date_type)[::-1] date_list = queryset.dates(date_field, date_type)[::-1]
if date_list is not None and not date_list and not allow_empty: if date_list is not None and not date_list and not allow_empty:
@ -400,7 +406,7 @@ class BaseArchiveIndexView(BaseDateListView):
Return (date_list, items, extra_context) for this request. Return (date_list, items, extra_context) for this request.
""" """
qs = self.get_dated_queryset(ordering='-%s' % self.get_date_field()) qs = self.get_dated_queryset(ordering='-%s' % self.get_date_field())
date_list = self.get_date_list(qs, 'year') date_list = self.get_date_list(qs)
if not date_list: if not date_list:
qs = qs.none() qs = qs.none()
@ -419,6 +425,7 @@ class BaseYearArchiveView(YearMixin, BaseDateListView):
""" """
List of objects published in a given year. List of objects published in a given year.
""" """
date_list_period = 'month'
make_object_list = False make_object_list = False
def get_dated_items(self): def get_dated_items(self):
@ -438,7 +445,7 @@ class BaseYearArchiveView(YearMixin, BaseDateListView):
} }
qs = self.get_dated_queryset(ordering='-%s' % date_field, **lookup_kwargs) qs = self.get_dated_queryset(ordering='-%s' % date_field, **lookup_kwargs)
date_list = self.get_date_list(qs, 'month') date_list = self.get_date_list(qs)
if not self.get_make_object_list(): if not self.get_make_object_list():
# We need this to be a queryset since parent classes introspect it # We need this to be a queryset since parent classes introspect it
@ -470,6 +477,8 @@ class BaseMonthArchiveView(YearMixin, MonthMixin, BaseDateListView):
""" """
List of objects published in a given year. List of objects published in a given year.
""" """
date_list_period = 'day'
def get_dated_items(self): def get_dated_items(self):
""" """
Return (date_list, items, extra_context) for this request. Return (date_list, items, extra_context) for this request.
@ -489,7 +498,7 @@ class BaseMonthArchiveView(YearMixin, MonthMixin, BaseDateListView):
} }
qs = self.get_dated_queryset(**lookup_kwargs) qs = self.get_dated_queryset(**lookup_kwargs)
date_list = self.get_date_list(qs, 'day') date_list = self.get_date_list(qs)
return (date_list, qs, { return (date_list, qs, {
'month': date, 'month': date,

View File

@ -29,6 +29,9 @@ ArchiveIndexView
* Uses a default ``context_object_name`` of ``latest``. * Uses a default ``context_object_name`` of ``latest``.
* Uses a default ``template_name_suffix`` of ``_archive``. * Uses a default ``template_name_suffix`` of ``_archive``.
* Defaults to providing ``date_list`` by year, but this can be altered to
month or day using the attribute ``date_list_period``. This also applies
to all subclass views.
YearArchiveView YearArchiveView
--------------- ---------------

View File

@ -60,7 +60,6 @@ class ArchiveIndexViewTests(TestCase):
res = self.client.get('/dates/books/allow_empty/') res = self.client.get('/dates/books/allow_empty/')
self.assertEqual(res.status_code, 200) self.assertEqual(res.status_code, 200)
self.assertEqual(list(res.context['date_list']), []) self.assertEqual(list(res.context['date_list']), [])
self.assertEqual(list(res.context['date_list']), [])
self.assertTemplateUsed(res, 'generic_views/book_archive.html') self.assertTemplateUsed(res, 'generic_views/book_archive.html')
def test_archive_view_template(self): def test_archive_view_template(self):
@ -80,6 +79,11 @@ class ArchiveIndexViewTests(TestCase):
def test_archive_view_invalid(self): def test_archive_view_invalid(self):
self.assertRaises(ImproperlyConfigured, self.client.get, '/dates/books/invalid/') self.assertRaises(ImproperlyConfigured, self.client.get, '/dates/books/invalid/')
def test_archive_view_by_month(self):
res = self.client.get('/dates/books/by_month/')
self.assertEqual(res.status_code, 200)
self.assertEqual(res.context['date_list'], Book.objects.dates('pubdate', 'month')[::-1])
def test_paginated_archive_view(self): def test_paginated_archive_view(self):
self._make_books(20, base_date=datetime.date.today()) self._make_books(20, base_date=datetime.date.today())
res = self.client.get('/dates/books/paginated/') res = self.client.get('/dates/books/paginated/')

View File

@ -113,6 +113,8 @@ urlpatterns = patterns('',
views.BookArchive.as_view(paginate_by=10)), views.BookArchive.as_view(paginate_by=10)),
(r'^dates/books/reverse/$', (r'^dates/books/reverse/$',
views.BookArchive.as_view(queryset=models.Book.objects.order_by('pubdate'))), views.BookArchive.as_view(queryset=models.Book.objects.order_by('pubdate'))),
(r'^dates/books/by_month/$',
views.BookArchive.as_view(date_list_period='month')),
(r'^dates/booksignings/$', (r'^dates/booksignings/$',
views.BookSigningArchive.as_view()), views.BookSigningArchive.as_view()),