Fixed #25807 -- Instructed the migration writer about lazy objects.

Thanks to Trac alias mrgaolei for the report, Baptiste for the confirmation
and Tim for the review.
This commit is contained in:
Simon Charette 2015-11-25 12:31:23 -05:00
parent 831514867c
commit cc2ca9c550
4 changed files with 16 additions and 3 deletions

View File

@ -19,7 +19,7 @@ from django.db.migrations.utils import COMPILED_REGEX_TYPE, RegexObject
from django.utils import datetime_safe, six
from django.utils._os import upath
from django.utils.encoding import force_text
from django.utils.functional import Promise
from django.utils.functional import LazyObject, Promise
from django.utils.inspect import get_func_args
from django.utils.module_loading import module_dir
from django.utils.timezone import now, utc
@ -350,6 +350,10 @@ class MigrationWriter(object):
# process.
if isinstance(value, Promise):
value = force_text(value)
elif isinstance(value, LazyObject):
# The unwrapped value is returned as the first item of the
# arguments tuple.
value = value.__reduce__()[1][0]
# Sequences
if isinstance(value, (frozenset, list, set, tuple)):

View File

@ -451,7 +451,8 @@ Migrations
:djadminopt:`migrate --fake-initial <--fake-initial>` to more easily detect
initial migrations.
* Added support for serialization of ``functools.partial`` objects.
* Added support for serialization of ``functools.partial`` and ``LazyObject``
instances.
* When supplying ``None`` as a value in :setting:`MIGRATION_MODULES`, Django
will consider the app an app without migrations.

View File

@ -648,6 +648,7 @@ Django can serialize the following:
- ``enum.Enum`` instances
- ``functools.partial`` instances which have serializable ``func``, ``args``,
and ``keywords`` values.
- ``LazyObject`` instances which wrap a serializable value.
- Any Django field
- Any function or method reference (e.g. ``datetime.datetime.today``) (must be in module's top-level scope)
- Any class reference (must be in module's top-level scope)
@ -655,7 +656,8 @@ Django can serialize the following:
.. versionchanged:: 1.9
Serialization support for `functools.partial` was added.
Serialization support for ``functools.partial`` and ``LazyObject``
instances was added.
.. versionchanged:: 1.10

View File

@ -23,6 +23,7 @@ from django.test import SimpleTestCase, ignore_warnings, mock
from django.utils import datetime_safe, six
from django.utils._os import upath
from django.utils.deconstruct import deconstructible
from django.utils.functional import SimpleLazyObject
from django.utils.timezone import FixedOffset, get_default_timezone, utc
from django.utils.translation import ugettext_lazy as _
@ -234,6 +235,11 @@ class WriterTests(SimpleTestCase):
("[list, tuple, dict, set, frozenset]", set())
)
def test_serialize_lazy_objects(self):
pattern = re.compile(r'^foo$', re.UNICODE)
lazy_pattern = SimpleLazyObject(lambda: pattern)
self.assertEqual(self.serialize_round_trip(lazy_pattern), pattern)
@unittest.skipUnless(enum, "enum34 is required on Python 2")
def test_serialize_enums(self):
class TextEnum(enum.Enum):