Opened 9 years ago

Closed 8 years ago

#3172 closed defect (fixed)

Model.validate raises TypeError on NULL for DateField, DateTimeField, and TimeField

Reported by: RahmCoff@… Owned by: adrian
Component: Database layer (models, ORM) Version: master
Severity: normal Keywords:
Cc: sam@…, floguy@… Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

When you have a model with any of the date/time fields, it throws a TypeError. For example:

class TestModel(models.Model):
    test_date = models.DateField()
    test_date_time = models.DateTimeField()
    test_time = models.TimeField()

TestModel().validate()

Traceback (most recent call last):
  File "<console>", line 1, in ?
  File "django/db/models/base.py", line 230, in validate
    setattr(self, f.attname, f.to_python(getattr(self, f.attname, f.get_default())))
  File "django/db/models/fields/__init__.py", line 435, in to_python
    validators.isValidANSIDate(value, None)
  File "django/core/validators.py", line 146, in isValidANSIDate
    if not ansi_date_re.search(field_data):
TypeError: expected string or buffer

Similar errors appear with DateTime and Time.

Attachments (1)

datetime_validation_fix_and_tests.patch (1.4 KB) - added by floguy@… 9 years ago.
Updated patch to revision 4427 and added unit tests.

Download all attachments as: .zip

Change History (9)

comment:1 Changed 9 years ago by russellm

  • Resolution set to invalid
  • Status changed from new to closed

Behaviour is as designed. TestModel() is a new, empty instance. The fields test_date, test_date_time and test_time don't yet have values. As a result, validation fails, as the fields do not have values that are a string or a DateTime instance.

comment:2 Changed 9 years ago by RahmCoff@…

  • Resolution invalid deleted
  • Status changed from closed to reopened
  • Summary changed from Model.validate fails on NULL for DateField, DateTimeField, and TimeField to Model.validate raises TypeError on NULL for DateField, DateTimeField, and TimeField

I'm sorry, I guess I didn't explain myself properly. validate() does not return a dict of problems, it throws a TypeError. Changing models.DateField() to models.DateField(null=True, blank=True) doesn't help either.

comment:3 Changed 9 years ago by RahmCoff@…

Diff for your viewing pleasure:

Index: django/db/models/fields/__init__.py
===================================================================
--- django/db/models/fields/__init__.py (revision 4236)
+++ django/db/models/fields/__init__.py (working copy)
@@ -428,6 +428,8 @@
         Field.__init__(self, verbose_name, name, **kwargs)
 
     def to_python(self, value):
+        if value is None:
+            return value
         if isinstance(value, datetime.datetime):
             return value.date()
         if isinstance(value, datetime.date):
@@ -488,6 +490,8 @@
 
 class DateTimeField(DateField):
     def to_python(self, value):
+        if value is None: 
+            return value
         if isinstance(value, datetime.datetime):
             return value
         if isinstance(value, datetime.date):

comment:4 Changed 9 years ago by jimmy@…

I experiencing the same problem.

comment:5 Changed 9 years ago by anonymous

  • Cc sam@… added

comment:6 Changed 9 years ago by SmileyChris

  • Has patch set
  • Needs tests set
  • Triage Stage changed from Unreviewed to Ready for checkin

It's obviously a bug. Probably could do with a regression test

Changed 9 years ago by floguy@…

Updated patch to revision 4427 and added unit tests.

comment:7 Changed 9 years ago by floguy@…

  • Cc floguy@… added
  • Needs tests unset

I have updated the patch which was posted here to revision 4427. Also, I have taken that test case which was given in the original post and converted it to a unit test which is also included in the patch. As long as this patch applies cleanly for others, it should be ready for production now. All regression tests pass as well.

comment:8 Changed 8 years ago by jacob

  • Resolution set to fixed
  • Status changed from reopened to closed

(In [4592]) Fixed #3172: Model.validate() no longer raises TypeErrors on empty Date*Fields. Thanks, floguy@….

Note: See TracTickets for help on using tickets.
Back to Top