Author: jezdez
Date: 2010-12-12 16:54:50 -0600 (Sun, 12 Dec 2010)
New Revision: 14879

Modified:
   django/trunk/django/contrib/admin/templatetags/admin_list.py
   django/trunk/docs/ref/contrib/admin/index.txt
   django/trunk/tests/regressiontests/admin_views/models.py
   django/trunk/tests/regressiontests/admin_views/tests.py
Log:
Fixed #13607 -- Auto-initialize admin's date hierarchy links intelligently. 
Thanks, Simon Meers.

Modified: django/trunk/django/contrib/admin/templatetags/admin_list.py
===================================================================
--- django/trunk/django/contrib/admin/templatetags/admin_list.py        
2010-12-12 22:54:22 UTC (rev 14878)
+++ django/trunk/django/contrib/admin/templatetags/admin_list.py        
2010-12-12 22:54:50 UTC (rev 14879)
@@ -231,6 +231,16 @@
 
         link = lambda d: cl.get_query_string(d, [field_generic])
 
+        if not (year_lookup or month_lookup or day_lookup):
+            # select appropriate start level
+            date_range = cl.query_set.aggregate(first=models.Min(field_name),
+                                                last=models.Max(field_name))
+            if date_range['first'] and date_range['last']:
+                if date_range['first'].year == date_range['last'].year:
+                    year_lookup = date_range['first'].year
+                    if date_range['first'].month == date_range['last'].month:
+                        month_lookup = date_range['first'].month
+
         if year_lookup and month_lookup and day_lookup:
             day = datetime.date(int(year_lookup), int(month_lookup), 
int(day_lookup))
             return {

Modified: django/trunk/docs/ref/contrib/admin/index.txt
===================================================================
--- django/trunk/docs/ref/contrib/admin/index.txt       2010-12-12 22:54:22 UTC 
(rev 14878)
+++ django/trunk/docs/ref/contrib/admin/index.txt       2010-12-12 22:54:50 UTC 
(rev 14879)
@@ -107,6 +107,12 @@
 
         date_hierarchy = 'pub_date'
 
+    .. versionadded:: 1.3
+
+        This will intelligently populate itself based on available data,
+        e.g. if all the dates are in one month, it'll show the day-level
+        drill-down only.
+
 .. attribute:: ModelAdmin.form
 
     By default a ``ModelForm`` is dynamically created for your model. It is

Modified: django/trunk/tests/regressiontests/admin_views/models.py
===================================================================
--- django/trunk/tests/regressiontests/admin_views/models.py    2010-12-12 
22:54:22 UTC (rev 14878)
+++ django/trunk/tests/regressiontests/admin_views/models.py    2010-12-12 
22:54:50 UTC (rev 14879)
@@ -320,7 +320,7 @@
 class PodcastAdmin(admin.ModelAdmin):
     list_display = ('name', 'release_date')
     list_editable = ('release_date',)
-
+    date_hierarchy = 'release_date'
     ordering = ('name',)
 
 class Vodcast(Media):

Modified: django/trunk/tests/regressiontests/admin_views/tests.py
===================================================================
--- django/trunk/tests/regressiontests/admin_views/tests.py     2010-12-12 
22:54:22 UTC (rev 14878)
+++ django/trunk/tests/regressiontests/admin_views/tests.py     2010-12-12 
22:54:50 UTC (rev 14879)
@@ -6,6 +6,7 @@
 from django.conf import settings
 from django.core import mail
 from django.core.files import temp as tempfile
+from django.core.urlresolvers import reverse
 # Register auth models with the admin.
 from django.contrib.auth import REDIRECT_FIELD_NAME, admin
 from django.contrib.auth.models import User, Permission, UNUSABLE_PASSWORD
@@ -2395,3 +2396,105 @@
         response = self.client.get('/test_admin/%s/admin_views/' % self.urlbit)
         self.assertFalse(' lang=""' in response.content)
         self.assertFalse(' xml:lang=""' in response.content)
+
+
+class DateHierarchyTests(TestCase):
+    fixtures = ['admin-views-users.xml']
+
+    def setUp(self):
+        self.client.login(username='super', password='secret')
+
+    def assert_contains_year_link(self, response, date):
+        self.assertContains(response, '?release_date__year=%d"' % (date.year,))
+
+    def assert_contains_month_link(self, response, date):
+        self.assertContains(
+            response, '?release_date__year=%d&release_date__month=%d"' % (
+                date.year, date.month))
+
+    def assert_contains_day_link(self, response, date):
+        self.assertContains(
+            response, '?release_date__year=%d&'
+            'release_date__month=%d&release_date__day=%d"' % (
+                date.year, date.month, date.day))
+
+    def test_empty(self):
+        """
+        Ensure that no date hierarchy links display with empty changelist.
+        """
+        response = self.client.get(
+            reverse('admin:admin_views_podcast_changelist'))
+        self.assertNotContains(response, 'release_date__year=')
+        self.assertNotContains(response, 'release_date__month=')
+        self.assertNotContains(response, 'release_date__day=')
+
+    def test_single(self):
+        """
+        Ensure that single day-level date hierarchy appears for single object.
+        """
+        DATE = datetime.date(2000, 6, 30)
+        Podcast.objects.create(release_date=DATE)
+        response = self.client.get(
+            reverse('admin:admin_views_podcast_changelist'))
+        self.assert_contains_day_link(response, DATE)
+
+    def test_within_month(self):
+        """
+        Ensure that day-level links appear for changelist within single month.
+        """
+        DATES = (datetime.date(2000, 6, 30),
+                 datetime.date(2000, 6, 15),
+                 datetime.date(2000, 6, 3))
+        for date in DATES:
+            Podcast.objects.create(release_date=date)
+        response = self.client.get(
+            reverse('admin:admin_views_podcast_changelist'))
+        for date in DATES:
+            self.assert_contains_day_link(response, date)
+
+    def test_within_year(self):
+        """
+        Ensure that month-level links appear for changelist within single year.
+        """
+        DATES = (datetime.date(2000, 1, 30),
+                 datetime.date(2000, 3, 15),
+                 datetime.date(2000, 5, 3))
+        for date in DATES:
+            Podcast.objects.create(release_date=date)
+        response = self.client.get(
+            reverse('admin:admin_views_podcast_changelist'))
+        # no day-level links
+        self.assertNotContains(response, 'release_date__day=')
+        for date in DATES:
+            self.assert_contains_month_link(response, date)
+
+    def test_multiple_years(self):
+        """
+        Ensure that year-level links appear for year-spanning changelist.
+        """
+        DATES = (datetime.date(2001, 1, 30),
+                 datetime.date(2003, 3, 15),
+                 datetime.date(2005, 5, 3))
+        for date in DATES:
+            Podcast.objects.create(release_date=date)
+        response = self.client.get(
+            reverse('admin:admin_views_podcast_changelist'))
+        # no day/month-level links
+        self.assertNotContains(response, 'release_date__day=')
+        self.assertNotContains(response, 'release_date__month=')
+        for date in DATES:
+            self.assert_contains_year_link(response, date)
+
+        # and make sure GET parameters still behave correctly
+        for date in DATES:
+            response = self.client.get(
+                '%s?release_date__year=%d' % (
+                    reverse('admin:admin_views_podcast_changelist'),
+                    date.year))
+            self.assert_contains_month_link(response, date)
+
+            response = self.client.get(
+                '%s?release_date__year=%d&release_date__month=%d' % (
+                    reverse('admin:admin_views_podcast_changelist'),
+                    date.year, date.month))
+            self.assert_contains_day_link(response, date)

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-upda...@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to