From 0516c5d9214372810dcf7d02f3a0f2705bb25a86 Mon Sep 17 00:00:00 2001 From: Malcolm Tredinnick Date: Tue, 10 Mar 2009 05:24:19 +0000 Subject: [PATCH] Fixed #10443 -- Fixed model attribute updating after r10003. 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). git-svn-id: http://code.djangoproject.com/svn/django/trunk@10013 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/models/base.py | 2 +- django/db/models/fields/__init__.py | 5 ++++ tests/regressiontests/model_regress/models.py | 25 ++++++++++++++++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/django/db/models/base.py b/django/db/models/base.py index c02ca04b1e..62ebbab7f0 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -376,7 +376,7 @@ class Model(object): manager.filter(pk=pk_val).extra(select={'a': 1}).values('a').order_by())): # It does already exist, so do an UPDATE. if force_update or non_pks: - values = [(f, None, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks] + values = [(f, None, (raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks] rows = manager.filter(pk=pk_val)._update(values) if force_update and not rows: raise DatabaseError("Forced update did not affect any rows.") diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 273416559c..bc41911ca3 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -821,6 +821,11 @@ class TimeField(Field): return None if isinstance(value, datetime.time): return value + if isinstance(value, datetime.datetime): + # Not usually a good idea to pass in a datetime here (it loses + # information), but this can be a side-effect of interacting with a + # database backend (e.g. Oracle), so we'll be accommodating. + return value.time # Attempt to parse a datetime: value = smart_str(value) diff --git a/tests/regressiontests/model_regress/models.py b/tests/regressiontests/model_regress/models.py index 625d9e3641..8d40c425ca 100644 --- a/tests/regressiontests/model_regress/models.py +++ b/tests/regressiontests/model_regress/models.py @@ -1,5 +1,9 @@ # coding: utf-8 +import datetime + +from django.conf import settings from django.db import models +from django.utils import tzinfo CHOICES = ( (1, 'first'), @@ -143,5 +147,24 @@ datetime.datetime(2000, 1, 1, 6, 1, 1) >>> BrokenUnicodeMethod.objects.all() [] +"""} + +if settings.DATABASE_ENGINE != "mysql": + __test__["non-mysql-tests"] = """ +# Saving an updating with timezone-aware datetime Python objects. Regression +# test for #10443. + +# The idea is that all these creations and saving should work without crashing. +# It's not rocket science. +>>> Article.objects.all().delete() +>>> dt1 = datetime.datetime(2008, 8, 31, 16, 20, tzinfo=tzinfo.FixedOffset(600)) +>>> dt2 = datetime.datetime(2008, 8, 31, 17, 20, tzinfo=tzinfo.FixedOffset(600)) +>>> obj = Article.objects.create(headline="A headline", pub_date=dt1, article_text="foo") + +>>> obj.pub_date = dt2 +>>> obj.save() +>>> Article.objects.filter(headline="A headline").update(pub_date=dt1) +1 + """ -} +