Ticket #13611: carls_cool_next_by_nullable_FOO.diff
File carls_cool_next_by_nullable_FOO.diff, 4.2 KB (added by , 14 years ago) |
---|
-
django/db/models/base.py
647 647 def _get_next_or_previous_by_FIELD(self, field, is_next, **kwargs): 648 648 op = is_next and 'gt' or 'lt' 649 649 order = not is_next and '-' or '' 650 param = smart_str(getattr(self, field.attname)) 651 q = Q(**{'%s__%s' % (field.name, op): param}) 652 q = q|Q(**{field.name: param, 'pk__%s' % op: self.pk}) 650 651 current_field_value = getattr(self, field.attname) 652 if current_field_value is None: 653 q = Q(**{ "%s__isnull" % field.name: True, 'pk__%s' % op: self.pk}) 654 else: 655 param = smart_str(current_field_value) 656 q = Q(**{'%s__%s' % (field.name, op): param}) 657 q = q|Q(**{field.name: param, 'pk__%s' % op: self.pk}) 658 653 659 qs = self.__class__._default_manager.using(self._state.db).filter(**kwargs).filter(q).order_by('%s%s' % (order, field.name), '%spk' % order) 654 660 try: 655 661 return qs[0] -
django/db/models/fields/__init__.py
627 627 628 628 def contribute_to_class(self, cls, name): 629 629 super(DateField,self).contribute_to_class(cls, name) 630 if not self.null: 631 setattr(cls, 'get_next_by_%s' % self.name, 632 curry(cls._get_next_or_previous_by_FIELD, field=self, is_next=True)) 633 setattr(cls, 'get_previous_by_%s' % self.name, 634 curry(cls._get_next_or_previous_by_FIELD, field=self, is_next=False)) 630 setattr(cls, 'get_next_by_%s' % self.name, 631 curry(cls._get_next_or_previous_by_FIELD, field=self, is_next=True)) 632 setattr(cls, 'get_previous_by_%s' % self.name, 633 curry(cls._get_next_or_previous_by_FIELD, field=self, is_next=False)) 635 634 636 635 def get_prep_lookup(self, lookup_type, value): 637 636 # For "__month", "__day", and "__week_day" lookups, convert the value -
tests/modeltests/lookup/models.py
9 9 10 10 class Article(models.Model): 11 11 headline = models.CharField(max_length=100) 12 pub_date = models.DateTimeField( )12 pub_date = models.DateTimeField(null=True) 13 13 class Meta: 14 14 ordering = ('-pub_date', 'headline') 15 15 … … 223 223 # get_previous_by_FOO() methods. 224 224 # In the case of identical date values, these methods will use the ID as a 225 225 # fallback check. This guarantees that no records are skipped or duplicated. 226 227 >>> a8 = Article(headline='Article 8', pub_date=None) 228 >>> a8.save() 229 >>> a9 = Article(headline='Article 9', pub_date=None) 230 >>> a9.save() 231 226 232 >>> a1.get_next_by_pub_date() 227 233 <Article: Article 2> 228 234 >>> a2.get_next_by_pub_date() … … 255 261 >>> a2.get_previous_by_pub_date() 256 262 <Article: Article 1> 257 263 264 # test walking around in null land: 265 266 # go from first null date to 2nd null date and back 267 >>> a8.get_next_by_pub_date() 268 <Article: Article 9> 269 >>> a9.get_previous_by_pub_date() 270 <Article: Article 8> 271 272 # try to go past first/last null date 273 a9.get_next_by_pub_date() 274 >>> a8.get_previous_by_pub_date() 275 Traceback (most recent call last): 276 ... 277 DoesNotExist: Article matching query does not exist. 278 >>> a9.get_next_by_pub_date() 279 Traceback (most recent call last): 280 ... 281 DoesNotExist: Article matching query does not exist. 282 283 # try to go from first date up into nulls (which SQL ORDER BY puts before values) 284 >>> a1.get_previous_by_pub_date() 285 Traceback (most recent call last): 286 ... 287 DoesNotExist: Article matching query does not exist. 288 289 # because I don't feel like modifying the rest of the tests: 290 >>> a8.delete() 291 >>> a9.delete() 292 258 293 # Underscores and percent signs have special meaning in the underlying 259 294 # SQL code, but Django handles the quoting of them automatically. 260 295 >>> a8 = Article(headline='Article_ with underscore', pub_date=datetime(2005, 11, 20))