Opened 6 years ago

Closed 6 years ago

Last modified 2 years ago

#11765 closed Uncategorized (invalid)

models.DateField(null=True, blank=True) accepts None, but not the empty string ''

Reported by: shmengie Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: yes Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by kmtracey)

For some reason I cannot create a record with

class MyModel(models.Model):
    models.DateField(null=True, blank=True)
MyModel(MyDateField='')  

It must be either None or a valid date.

Change History (8)

comment:1 Changed 6 years ago by mrts

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Summary changed from models.DateField(null=True, blank=True) accepts None, but not null string '' to models.DateField(null=True, blank=True) accepts None, but not the empty string ''

comment:2 follow-up: Changed 6 years ago by mrts

  • Component changed from Uncategorized to Database layer (models, ORM)
  • Needs tests set
  • Version changed from 1.1 to SVN

The problem is that DateField.to_python() (or DateTimeField) doesn't treat '' specially, see source:/django/trunk/django/db/models/fields/__init__.py@10545#L464

class DateTest(models.Model):
    foo = models.DateField(null=True, blank=True)
>>> d = DateTest(foo='')
>>> d.save()
Traceback (most recent call last):
  ...
  File "/usr/lib/python2.6/dist-packages/django/db/models/fields/__init__.py", line 474, in to_python
    _('Enter a valid date in YYYY-MM-DD format.'))
ValidationError: Enter a valid date in YYYY-MM-DD format.

comment:3 Changed 6 years ago by iapain

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

blank=True tells user that they don't have to fill this field, and it doesn't mean that its empty string. Django assign NoneType if empty.

comment:4 in reply to: ↑ 2 Changed 6 years ago by kmtracey

  • Description modified (diff)

Replying to mrts:

The problem is that DateField.to_python() (or DateTimeField) doesn't treat '' specially...

Neither does IntegerField nor FloatField, eg. It's not clear to me why Date fields would/should be singled out for special treatment here. Forms fields consistently handle treating empty strings input as None, but if you are operating at the model level then you need to use None when you mean None, not an empty string.

comment:5 follow-up: Changed 6 years ago by imbaczek@…

i've got the ValidationError exception in django's own create_update generic view. a ModelForm instance validates fine, but the save() method raises exactly this exception. there's a simple workaround, but IMHO it should be performed by the field instance.

    def clean(self):
        cleaned_data = self.cleaned_data
        end_time = cleaned_data.get('end_time') # this is not None if user left the <input/> empty

        # ... do stuff with data

        if not end_time:
            cleaned_data['end_time'] = None

        return cleaned_data

not sure if it warrants a different ticket.

comment:6 Changed 6 years ago by tclancy

In case it helps anyone else tearing their hair out, here's one other thing to check (see Stack Overflow ticket): if you have any default or helper text in the field, that will blow up on validation before you get to the clean() method.

comment:7 in reply to: ↑ 5 Changed 2 years ago by Brendan

  • Easy pickings unset
  • Severity set to Normal
  • Type set to Uncategorized
  • UI/UX unset

I agree, I just fixed my problem by adding

    def clean(self):
        cleaned_data = super(MyForm, self).clean()
        if not cleaned_data['my_date']:
            cleaned_data['my_date'] = None
        return cleaned_data

to my form. Without this I received the error

ValidationError: [u"'' value has an invalid date format. It must be in YYYY-MM-DD format."]

even though I had blank=True, null=True set in my model and required=False set in my form.

comment:8 Changed 2 years ago by yekibud

I got this error using crispy-forms and not specifying my Date field in Meta.fields. Adding a clean()n method didn't help but adding the Date field back to Meta.fields did.

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