diff --git a/django/db/models/base.py b/django/db/models/base.py
index 53b62df..fc38224 100644
a
|
b
|
from django.db.models.options import Options
|
20 | 20 | from django.db.models import signals |
21 | 21 | from django.db.models.loading import register_models, get_model |
22 | 22 | from django.utils.translation import ugettext_lazy as _ |
23 | | from django.utils.functional import curry, Promise |
| 23 | from django.utils.functional import curry |
24 | 24 | from django.utils.encoding import smart_str, force_unicode |
25 | 25 | from django.utils.text import get_text_list, capfirst |
26 | 26 | |
… |
… |
class Model(object):
|
297 | 297 | # is *not* consumed. We rely on this, so don't change the order |
298 | 298 | # without changing the logic. |
299 | 299 | for val, field in izip(args, fields_iter): |
300 | | if isinstance(val, Promise): |
301 | | val = force_unicode(val) |
302 | 300 | setattr(self, field.attname, val) |
303 | 301 | else: |
304 | 302 | # Slower, kwargs-ready version. |
305 | 303 | for val, field in izip(args, fields_iter): |
306 | | if isinstance(val, Promise): |
307 | | val = force_unicode(val) |
308 | 304 | setattr(self, field.attname, val) |
309 | 305 | kwargs.pop(field.name, None) |
310 | 306 | # Maintain compatibility with existing calls. |
… |
… |
class Model(object):
|
358 | 354 | # checked) by the RelatedObjectDescriptor. |
359 | 355 | setattr(self, field.name, rel_obj) |
360 | 356 | else: |
361 | | if isinstance(val, Promise): |
362 | | val = force_unicode(val) |
363 | 357 | setattr(self, field.attname, val) |
364 | 358 | |
365 | 359 | if kwargs: |
diff --git a/django/db/models/sql/subqueries.py b/django/db/models/sql/subqueries.py
index 1b03647..4652c93 100644
a
|
b
|
from django.db.models.sql.constants import *
|
8 | 8 | from django.db.models.sql.datastructures import Date |
9 | 9 | from django.db.models.sql.query import Query |
10 | 10 | from django.db.models.sql.where import AND, Constraint |
| 11 | from django.utils.functional import Promise |
| 12 | from django.utils.encoding import force_unicode |
11 | 13 | |
12 | 14 | |
13 | 15 | __all__ = ['DeleteQuery', 'UpdateQuery', 'InsertQuery', 'DateQuery', |
… |
… |
class UpdateQuery(Query):
|
101 | 103 | Used by add_update_values() as well as the "fast" update path when |
102 | 104 | saving models. |
103 | 105 | """ |
| 106 | # Check that no Promise object passes to the query. Refs #10498. |
| 107 | values_seq = [(v[0], v[1], force_unicode(v[2])) if isinstance(v[2], Promise) else v for v in values_seq] |
104 | 108 | self.values.extend(values_seq) |
105 | 109 | |
106 | 110 | def add_related_update(self, model, field, value): |
… |
… |
class InsertQuery(Query):
|
159 | 163 | into the query, for example. |
160 | 164 | """ |
161 | 165 | self.fields = fields |
| 166 | # Check that no Promise object passes to the DB. Refs #10498. |
| 167 | for field in fields: |
| 168 | for obj in objs: |
| 169 | fval = getattr(obj, field.attname) |
| 170 | if isinstance(fval, Promise): |
| 171 | setattr(obj, field.attname, force_unicode(fval)) |
162 | 172 | self.objs = objs |
163 | 173 | self.raw = raw |
164 | 174 | |
diff --git a/tests/modeltests/basic/tests.py b/tests/modeltests/basic/tests.py
index 30ed3de..f9141dc 100644
a
|
b
|
from datetime import datetime
|
5 | 5 | from django.core.exceptions import ObjectDoesNotExist |
6 | 6 | from django.db.models.fields import FieldDoesNotExist |
7 | 7 | from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature |
| 8 | from django.utils.translation import ugettext_lazy |
8 | 9 | |
9 | 10 | from .models import Article |
10 | 11 | |
… |
… |
class ModelTest(TestCase):
|
553 | 554 | pub_date__year=2008).extra( |
554 | 555 | select={'dashed-value': '1', 'undashedvalue': '2'}) |
555 | 556 | self.assertEqual(articles[0].undashedvalue, 2) |
| 557 | |
| 558 | def test_create_relation_with_ugettext_lazy(self): |
| 559 | """ |
| 560 | Test that ugettext_lazy objects work when saving model instances |
| 561 | through various methods. Refs #10498. |
| 562 | """ |
| 563 | notlazy = u'test' |
| 564 | lazy = ugettext_lazy(notlazy) |
| 565 | reporter = Article.objects.create(headline=lazy, pub_date=datetime.now()) |
| 566 | article = Article.objects.get() |
| 567 | self.assertEqual(article.headline, notlazy) |
| 568 | # test that assign + save works with Promise objecs |
| 569 | article.headline = lazy |
| 570 | article.save() |
| 571 | self.assertEqual(article.headline, notlazy) |
| 572 | # test .update() |
| 573 | Article.objects.update(headline=lazy) |
| 574 | article = Article.objects.get() |
| 575 | self.assertEqual(article.headline, notlazy) |
| 576 | # still test bulk_create() |
| 577 | Article.objects.all().delete() |
| 578 | Article.objects.bulk_create([Article(headline=lazy, pub_date=datetime.now())]) |
| 579 | article = Article.objects.get() |
| 580 | self.assertEqual(article.headline, notlazy) |