#2192 closed defect (fixed)
[patch] DateField with unique=True breaks
Reported by: | anonymous | Owned by: | Adrian Holovaty |
---|---|---|---|
Component: | contrib.admin | Version: | dev |
Severity: | major | Keywords: | DateField unique breaks |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
The following model breaks, when I try to add an object in the admin.
from django.db import models class Foo(models.Model): the_date = models.DateField('Watch me screw up', unique=True) class Admin: pass
With the following error:
AttributeError at /admin/foo/foo/add/ 'str' object has no attribute 'strftime' Request Method: POST Request URL: http://localhost/admin/foo/foo/add/ Exception Type: AttributeError Exception Value: 'str' object has no attribute 'strftime' Exception Location: /home/anonymous/django/latest/django/db/models/fields/__init__.py in get_db_prep_lookup, line 415
Attachments (2)
Change History (9)
comment:1 by , 18 years ago
comment:2 by , 18 years ago
priority: | normal → high |
---|
comment:3 by , 18 years ago
Severity: | normal → major |
---|
comment:4 by , 18 years ago
This only happens with DateField
. DateTimeField
and TimeField
work fine. The cause is the following lines added in r2517 to db.models.fields.DateField.get_db_prep_lookup
:
elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'ne'): value = value.strftime('%Y-%m-%d')
I don't follow the commit log, but it seems odd this would be needed just for DateFields
and not the rest. The following is a workaround if the lines need to stay. Just convert back to datetime.date if needed.
Patch:
--- django/db/models/fields/__init__.py (revision 3194) +++ django/db/models/fields/__init__.py (working copy) @@ -412,6 +412,8 @@ if lookup_type == 'range': value = [str(v) for v in value] elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'ne'): + if type(value) is str: + value = self.to_python(value) value = value.strftime('%Y-%m-%d') else: value = str(value)
by , 18 years ago
Attachment: | datefield_unique.diff added |
---|
Convert string to datetime.date in DateField.get_db_prep_lookup if needed.
comment:5 by , 18 years ago
Summary: | DateField with unique=True breaks → [patch] DateField with unique=True breaks |
---|
Change Summary to indicate patch. (Sorry about the first inline patch.)
by , 18 years ago
Attachment: | datefield_unique.2.diff added |
---|
New version of patch. Just check for string first, rather than convert to object, only to go back to string.
After some poking around, it looks like the problem here is that when
django.db.models.fields.manipulator_validator_unique
tries to do a lookup to see if an object with the same date exists, it's not turning the string into adatetime.date
object, just continuing to handle it as a string. I'd imagine that trying this with aDateTimeField
orTimeField
would yield similar problems.So it looks like we need to do some introspection of the field type in there and convert to an appropriate type for doing the lookup.