Code

Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#2192 closed defect (fixed)

[patch] DateField with unique=True breaks

Reported by: anonymous Owned by: adrian
Component: contrib.admin Version: master
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: UI/UX:

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@… 8 years ago.
Convert string to datetime.date in DateField.get_db_prep_lookup if needed.
datefield_unique.2.diff (644 bytes) - added by deryck@… 8 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 Changed 8 years ago by ubernostrum

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 Changed 8 years ago by anonymous

  • priority changed from normal to high

comment:3 Changed 8 years ago by anonymous

  • Severity changed from normal to major

comment:4 Changed 8 years ago by deryck@…

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)

Changed 8 years ago by deryck@…

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

comment:5 Changed 8 years ago by deryck@…

  • Summary changed from DateField with unique=True breaks to [patch] DateField with unique=True breaks

Change Summary to indicate patch. (Sorry about the first inline patch.)

Changed 8 years ago by deryck@…

New version of patch. Just check for string first, rather than convert to object, only to go back to string.

comment:6 Changed 8 years ago by anonymous

this patch seemed to do the trick for me

comment:7 Changed 8 years ago by mtredinnick

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

(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.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.