#10443 closed (fixed)
Updating Timezone Aware DateTimeField Fails
Reported by: | Simon Blanchard | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Keywords: | ||
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | yes | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
Changeset [10003] sends updates through get_db_prep_save. In the DateTimeField this calls to_python which parses a string. If the string looks like this: 2009-03-09 10:22:49.834296 It works. If the string looks like this: 2009-03-09 10:23:14.439863+00:00 It fails. Attached patch fixes it. But I think we need to actually do something with the timezone info.
Attachments (2)
Change History (8)
by , 16 years ago
comment:1 by , 16 years ago
Component: | Core framework → Database layer (models, ORM) |
---|---|
Needs tests: | set |
Patch needs improvement: | set |
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 16 years ago
Malcolm,
I understand that the last thing you need here is anecdotal evidence, but I've experienced the same issue and can verify where binding a tz-aware datetime object to a DateTimeField works on creation but fails on update (here, at least).
A cursory examination leads me to observe that the following bits in UpdateQuery.add_update_fields that were added in [10003]:
if hasattr(val, 'prepare_database_save'): val = val.prepare_database_save(field) else: val = field.get_db_prep_save(val)
are _not_ present in InsertQuery.insert_values. When initially setting a DateTimeField a tz-aware datetime object is passed as-is, whereas on update it is passed as a unicode object - which triggers the ValidationError.
comment:3 by , 16 years ago
Yes. It really does only happen with updates. I'll attach an example project which demonstrates the issue. The traceback is shown below.
The example uses pytz http://pytz.sourceforge.net/ which greatly takes the tedium out of tz aware applications.
Traceback (most recent call last):
File "test.py", line 12, in <module>
sctz.save()
File "/Users/simonb/src/dj/bugs/savebug/bug/models.py", line 33, in save
super(SomeClassTZ, self).save(force_insert=force_insert, force_update=force_update)
File "/Users/simonb/src/dj/versions/trunk/django/db/models/base.py", line 329, in save
self.save_base(force_insert=force_insert, force_update=force_update)
File "/Users/simonb/src/dj/versions/trunk/django/db/models/base.py", line 380, in save_base
rows = manager.filter(pk=pk_val)._update(values)
File "/Users/simonb/src/dj/versions/trunk/django/db/models/query.py", line 466, in _update
query.add_update_fields(values)
File "/Users/simonb/src/dj/versions/trunk/django/db/models/sql/subqueries.py", line 245, in add_update_fields
val = field.get_db_prep_save(val)
File "/Users/simonb/src/dj/versions/trunk/django/db/models/fields/init.py", line 192, in get_db_prep_save
return self.get_db_prep_value(value)
File "/Users/simonb/src/dj/versions/trunk/django/db/models/fields/init.py", line 562, in get_db_prep_value
return connection.ops.value_to_db_datetime(self.to_python(value))
File "/Users/simonb/src/dj/versions/trunk/django/db/models/fields/init.py", line 540, in to_python
_('Enter a valid date/time in YYYY-MM-DD HH:MM[:ss[.uuuuuu]] format.'))
django.core.exceptions.ValidationError: Enter a valid date/time in YYYY-MM-DD HH:MM[:ss[.uuuuuu]] format.
by , 16 years ago
Attachment: | savebug.zip added |
---|
Example project showing bug when saving tz aware DateTimeField
comment:4 by , 16 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
(In [10014]) [1.0.X] Fixed #10443 -- Fixed model attribute updating after r10004.
Adding a get_db_prep_save() call to the UpdateQuery code path meant it
was being called twice if you updated an existing model attribute. This
change removes that double call and also makes TimeField.to_python() a
little more robust for the benefit of the Oracle backend (just in case).
Backport of r10013 from trunk.
Django's datetime fields are timezone-unaware at the moment. We'll keep it that way for now, for consistency. One day it would be nice to have a datetime-with-timezone field, but that's another ticket (in fact, there are one or two of them open, from memory).
On the subject of the patch, I'm kind of surprised this doesn't need a similar change for saving a model initially, since it uses the same code paths now. Does the same value really work at model creation, but not for updates?
Needs a test case that fails beforehand and passes afterwards.