Opened 15 years ago

Closed 15 years ago

Last modified 15 years ago

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

dt.diff (652 bytes ) - added by Simon Blanchard 15 years ago.
savebug.zip (5.0 KB ) - added by Simon Blanchard 15 years ago.
Example project showing bug when saving tz aware DateTimeField

Download all attachments as: .zip

Change History (8)

by Simon Blanchard, 15 years ago

Attachment: dt.diff added

comment:1 by Malcolm Tredinnick, 15 years ago

Component: Core frameworkDatabase layer (models, ORM)
Needs tests: set
Patch needs improvement: set
Triage Stage: UnreviewedAccepted

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.

comment:2 by yorkedork, 15 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 Simon Blanchard, 15 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 Simon Blanchard, 15 years ago

Attachment: savebug.zip added

Example project showing bug when saving tz aware DateTimeField

comment:4 by Malcolm Tredinnick, 15 years ago

Resolution: fixed
Status: newclosed

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

comment:5 by Erin Kelly, 15 years ago

(In [10024]) Refs #10443: Added Oracle to the #10443 regression test exemption, since we don't yet support it.

comment:6 by Erin Kelly, 15 years ago

(In [10025]) [1.0.X] Backport of [10024] from trunk. Refs #10443: Added Oracle to the #10443 regression test exemption, since we don't yet support it.

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