1. Luke Plant
  2. django-easyfilters

Commits

Luke Plant  committed 32462fb

Fixed end range of DateTimeFilter so that it respects the number of days in the month and doesn't wrap to the next month

Fixes issue #3

  • Participants
  • Parent commits 0bffeed
  • Branches default

Comments (0)

Files changed (3)

File CHANGES.rst

View file
 * Added and documented ``Filter.render_choice_object`` which can
   be overridden for easy customization of filters.
 
+* Fixed various bugs with DateTimeFilter
+
 Version 0.3.2
 -------------
 

File django_easyfilters/filters.py

View file
             if range_type is MONTH:
                 first, last = 1, 12
             elif range_type is DAY:
-                first, last = 1, 31
+                first, last = 1, (results[0][0] + relativedelta(months=1, days=-1)).day
             else:
                 first = results[0][0].year
                 last = results[-1][0].year
             for i, bucket in enumerate(buckets):
                 count = sum(row[1] for row in bucket)
                 start_val = first + bucketsize * i
+                end_val = min(start_val + bucketsize, last)
                 start_date = dt_template.replace(**dict({range_type.dateattr: start_val}))
-                end_date = start_date + relativedelta(**dict({range_type.relativedeltaattr: bucketsize - 1}))
+                end_date = dt_template.replace(**dict({range_type.dateattr: end_val}))
 
                 choice = DateChoice.from_datetime_range(range_type, start_date, end_date)
                 date_choice_counts.append((choice, count))
         # (which might be nothing) to what can be chosen, to give context to the
         # link.
 
-        # Note this is used is bridging to the 'add' choices, and in bridging
+        # Note this is used in bridging to the 'add' choices, and in bridging
         # between 'remove' choices
 
         if len(choices) == 0:

File django_easyfilters/tests/filterset.py

View file
         # Expect '10' and '20' as choices
         self.assertEqual(['10', '20'], [c.label for c in choices if c.link_type == FILTER_ADD])
 
+    def test_datetime_filter_day_ranges_end(self):
+        """
+        Test that the ranges for day selection end at the right point (e.g. 31)
+        """
+        # September
+        for i in range(1, 30):
+            Person.objects.create(name="Joe", date_of_birth=date(2011, 9, i))
+
+        params = MultiValueDict({'date_of_birth':['2011-09']})
+
+        f = DateTimeFilter('date_of_birth', Person, params)
+        qs = Person.objects.all()
+        qs_filtered = f.apply_filter(qs)
+        choices = f.get_choices(qs_filtered)
+        self.assertEqual(choices[-1].label[-3:], "-30")
+
+        # October
+        for i in range(1, 31):
+            Person.objects.create(name="Joe", date_of_birth=date(2011, 10, i))
+
+        params = MultiValueDict({'date_of_birth':['2011-10']})
+
+        f = DateTimeFilter('date_of_birth', Person, params)
+        qs = Person.objects.all()
+        qs_filtered = f.apply_filter(qs)
+        choices = f.get_choices(qs_filtered)
+        self.assertEqual(choices[-1].label[-3:], "-31")
+
     def test_numericrange_filter_simple_vals(self):
         # If data is less than max_links, we should get a simple list of values.
         filter1 = NumericRangeFilter('price', Book, MultiValueDict(), max_links=20)