Opened 18 years ago

Closed 18 years ago

Last modified 17 years ago

#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)

datefield_unique.diff (573 bytes ) - added by deryck@… 18 years ago.
Convert string to datetime.date in DateField.get_db_prep_lookup if needed.
datefield_unique.2.diff (644 bytes ) - added by deryck@… 18 years ago.
New version of patch. Just check for string first, rather than convert to object, only to go back to string.

Download all attachments as: .zip

Change History (9)

comment:1 by James Bennett, 18 years ago

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 a datetime.date object, just continuing to handle it as a string. I'd imagine that trying this with a DateTimeField or TimeField 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.

comment:2 by anonymous, 18 years ago

priority: normalhigh

comment:3 by anonymous, 18 years ago

Severity: normalmajor

comment:4 by deryck@…, 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 deryck@…, 18 years ago

Attachment: datefield_unique.diff added

Convert string to datetime.date in DateField.get_db_prep_lookup if needed.

comment:5 by deryck@…, 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 deryck@…, 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.

comment:6 by anonymous, 18 years ago

this patch seemed to do the trick for me

comment:7 by Malcolm Tredinnick, 18 years ago

Resolution: fixed
Status: newclosed

(In [3223]) Fixed #1754, #2211, #2192 -- allow date filtering comparisons to use strings as
well as date objects. Fixed a couple of admin crashes as well.

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