Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #10498 (again) -- Made sure the improvements done in r17641 hav…

…e a smaller impact on speed. Thanks to Anssi Kääriäinen for the patch and Jonas Obrist for reviewing.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17698 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit f7daa38a0025da1613e772af2aec419169b086cc 1 parent 0ee801e
@jezdez jezdez authored
View
8 django/db/models/base.py
@@ -20,7 +20,7 @@
from django.db.models import signals
from django.db.models.loading import register_models, get_model
from django.utils.translation import ugettext_lazy as _
-from django.utils.functional import curry, Promise
+from django.utils.functional import curry
from django.utils.encoding import smart_str, force_unicode
from django.utils.text import get_text_list, capfirst
@@ -297,14 +297,10 @@ def __init__(self, *args, **kwargs):
# is *not* consumed. We rely on this, so don't change the order
# without changing the logic.
for val, field in izip(args, fields_iter):
- if isinstance(val, Promise):
- val = force_unicode(val)
setattr(self, field.attname, val)
else:
# Slower, kwargs-ready version.
for val, field in izip(args, fields_iter):
- if isinstance(val, Promise):
- val = force_unicode(val)
setattr(self, field.attname, val)
kwargs.pop(field.name, None)
# Maintain compatibility with existing calls.
@@ -358,8 +354,6 @@ def __init__(self, *args, **kwargs):
# checked) by the RelatedObjectDescriptor.
setattr(self, field.name, rel_obj)
else:
- if isinstance(val, Promise):
- val = force_unicode(val)
setattr(self, field.attname, val)
if kwargs:
View
17 django/db/models/sql/subqueries.py
@@ -8,6 +8,8 @@
from django.db.models.sql.datastructures import Date
from django.db.models.sql.query import Query
from django.db.models.sql.where import AND, Constraint
+from django.utils.functional import Promise
+from django.utils.encoding import force_unicode
__all__ = ['DeleteQuery', 'UpdateQuery', 'InsertQuery', 'DateQuery',
@@ -38,7 +40,7 @@ def delete_batch(self, pk_list, using, field=None):
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
where = self.where_class()
where.add((Constraint(None, field.column, field), 'in',
- pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]), AND)
+ pk_list[offset:offset + GET_ITERATOR_CHUNK_SIZE]), AND)
self.do_query(self.model._meta.db_table, where, using=using)
class UpdateQuery(Query):
@@ -67,14 +69,13 @@ def clone(self, klass=None, **kwargs):
return super(UpdateQuery, self).clone(klass,
related_updates=self.related_updates.copy(), **kwargs)
-
def update_batch(self, pk_list, values, using):
pk_field = self.model._meta.pk
self.add_update_values(values)
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
self.where = self.where_class()
self.where.add((Constraint(None, pk_field.column, pk_field), 'in',
- pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]),
+ pk_list[offset:offset + GET_ITERATOR_CHUNK_SIZE]),
AND)
self.get_compiler(using).execute_sql(None)
@@ -101,6 +102,10 @@ def add_update_fields(self, values_seq):
Used by add_update_values() as well as the "fast" update path when
saving models.
"""
+ # Check that no Promise object passes to the query. Refs #10498.
+ values_seq = [(value[0], value[1], force_unicode(value[2]))
+ if isinstance(value[2], Promise) else value
+ for value in values_seq]
self.values.extend(values_seq)
def add_related_update(self, model, field, value):
@@ -159,6 +164,12 @@ def insert_values(self, fields, objs, raw=False):
into the query, for example.
"""
self.fields = fields
+ # Check that no Promise object reaches the DB. Refs #10498.
+ for field in fields:
+ for obj in objs:
+ value = getattr(obj, field.attname)
+ if isinstance(value, Promise):
+ setattr(obj, field.attname, force_unicode(value))
self.objs = objs
self.raw = raw
View
25 tests/modeltests/basic/tests.py
@@ -5,6 +5,7 @@
from django.core.exceptions import ObjectDoesNotExist
from django.db.models.fields import FieldDoesNotExist
from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
+from django.utils.translation import ugettext_lazy
from .models import Article
@@ -553,3 +554,27 @@ def test_extra_method_select_argument_with_dashes(self):
pub_date__year=2008).extra(
select={'dashed-value': '1', 'undashedvalue': '2'})
self.assertEqual(articles[0].undashedvalue, 2)
+
+ def test_create_relation_with_ugettext_lazy(self):
+ """
+ Test that ugettext_lazy objects work when saving model instances
+ through various methods. Refs #10498.
+ """
+ notlazy = u'test'
+ lazy = ugettext_lazy(notlazy)
+ reporter = Article.objects.create(headline=lazy, pub_date=datetime.now())
+ article = Article.objects.get()
+ self.assertEqual(article.headline, notlazy)
+ # test that assign + save works with Promise objecs
+ article.headline = lazy
+ article.save()
+ self.assertEqual(article.headline, notlazy)
+ # test .update()
+ Article.objects.update(headline=lazy)
+ article = Article.objects.get()
+ self.assertEqual(article.headline, notlazy)
+ # still test bulk_create()
+ Article.objects.all().delete()
+ Article.objects.bulk_create([Article(headline=lazy, pub_date=datetime.now())])
+ article = Article.objects.get()
+ self.assertEqual(article.headline, notlazy)
Please sign in to comment.
Something went wrong with that request. Please try again.