Browse Source

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

Resolving the concept from a very old ticket in a more class-based-view
manner.
Marc Tamlyn 12 years ago
parent
commit
8d5c11caad

+ 13 - 4
django/views/generic/dates.py

@@ -327,6 +327,7 @@ class BaseDateListView(MultipleObjectMixin, DateMixin, View):
     Abstract base class for date-based views displaying a list of objects.
     """
     allow_empty = False
+    date_list_period = 'year'
 
     def get(self, request, *args, **kwargs):
         self.date_list, self.object_list, extra_context = self.get_dated_items()
@@ -370,13 +371,18 @@ class BaseDateListView(MultipleObjectMixin, DateMixin, View):
 
         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
         for empty lists that aren't allowed.
         """
         date_field = self.get_date_field()
         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]
         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.
         """
         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:
             qs = qs.none()
@@ -419,6 +425,7 @@ class BaseYearArchiveView(YearMixin, BaseDateListView):
     """
     List of objects published in a given year.
     """
+    date_list_period = 'month'
     make_object_list = False
 
     def get_dated_items(self):
@@ -438,7 +445,7 @@ class BaseYearArchiveView(YearMixin, BaseDateListView):
         }
 
         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():
             # 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.
     """
+    date_list_period = 'day'
+
     def get_dated_items(self):
         """
         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)
-        date_list = self.get_date_list(qs, 'day')
+        date_list = self.get_date_list(qs)
 
         return (date_list, qs, {
             'month': date,

+ 3 - 0
docs/ref/class-based-views/generic-date-based.txt

@@ -29,6 +29,9 @@ ArchiveIndexView
 
     * Uses a default ``context_object_name`` of ``latest``.
     * 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
 ---------------

+ 5 - 1
tests/regressiontests/generic_views/dates.py

@@ -60,7 +60,6 @@ class ArchiveIndexViewTests(TestCase):
         res = self.client.get('/dates/books/allow_empty/')
         self.assertEqual(res.status_code, 200)
         self.assertEqual(list(res.context['date_list']), [])
-        self.assertEqual(list(res.context['date_list']), [])
         self.assertTemplateUsed(res, 'generic_views/book_archive.html')
 
     def test_archive_view_template(self):
@@ -80,6 +79,11 @@ class ArchiveIndexViewTests(TestCase):
     def test_archive_view_invalid(self):
         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):
         self._make_books(20, base_date=datetime.date.today())
         res = self.client.get('/dates/books/paginated/')

+ 2 - 0
tests/regressiontests/generic_views/urls.py

@@ -113,6 +113,8 @@ urlpatterns = patterns('',
         views.BookArchive.as_view(paginate_by=10)),
     (r'^dates/books/reverse/$',
         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/$',
         views.BookSigningArchive.as_view()),