Fixed #27378 -- Added support for serialization of uuid.UUID in migrations.
Thanks Yuriy Korobko for the initial patch and Tobias McNulty for review.
This commit is contained in:
parent
7301770254
commit
cb3fb34b86
|
@ -6,6 +6,7 @@ import decimal
|
||||||
import functools
|
import functools
|
||||||
import math
|
import math
|
||||||
import types
|
import types
|
||||||
|
import uuid
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
@ -320,6 +321,11 @@ class TypeSerializer(BaseSerializer):
|
||||||
return "%s.%s" % (module, self.value.__name__), {"import %s" % module}
|
return "%s.%s" % (module, self.value.__name__), {"import %s" % module}
|
||||||
|
|
||||||
|
|
||||||
|
class UUIDSerializer(BaseSerializer):
|
||||||
|
def serialize(self):
|
||||||
|
return "uuid.%s" % repr(self.value), {"import uuid"}
|
||||||
|
|
||||||
|
|
||||||
def serializer_factory(value):
|
def serializer_factory(value):
|
||||||
from django.db.migrations.writer import SettingsReference
|
from django.db.migrations.writer import SettingsReference
|
||||||
if isinstance(value, Promise):
|
if isinstance(value, Promise):
|
||||||
|
@ -382,6 +388,8 @@ def serializer_factory(value):
|
||||||
return IterableSerializer(value)
|
return IterableSerializer(value)
|
||||||
if isinstance(value, (COMPILED_REGEX_TYPE, RegexObject)):
|
if isinstance(value, (COMPILED_REGEX_TYPE, RegexObject)):
|
||||||
return RegexSerializer(value)
|
return RegexSerializer(value)
|
||||||
|
if isinstance(value, uuid.UUID):
|
||||||
|
return UUIDSerializer(value)
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Cannot serialize: %r\nThere are some values Django cannot serialize into "
|
"Cannot serialize: %r\nThere are some values Django cannot serialize into "
|
||||||
"migration files.\nFor more, see https://docs.djangoproject.com/en/%s/"
|
"migration files.\nFor more, see https://docs.djangoproject.com/en/%s/"
|
||||||
|
|
|
@ -286,7 +286,7 @@ Management Commands
|
||||||
Migrations
|
Migrations
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
* ...
|
* Added support for serialization of ``uuid.UUID`` objects.
|
||||||
|
|
||||||
Models
|
Models
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
|
@ -670,6 +670,7 @@ Django can serialize the following:
|
||||||
(include those that are timezone-aware)
|
(include those that are timezone-aware)
|
||||||
- ``decimal.Decimal`` instances
|
- ``decimal.Decimal`` instances
|
||||||
- ``enum.Enum`` instances
|
- ``enum.Enum`` instances
|
||||||
|
- ``uuid.UUID`` instances
|
||||||
- ``functools.partial`` instances which have serializable ``func``, ``args``,
|
- ``functools.partial`` instances which have serializable ``func``, ``args``,
|
||||||
and ``keywords`` values.
|
and ``keywords`` values.
|
||||||
- ``LazyObject`` instances which wrap a serializable value.
|
- ``LazyObject`` instances which wrap a serializable value.
|
||||||
|
@ -682,6 +683,10 @@ Django can serialize the following:
|
||||||
|
|
||||||
Serialization support for ``enum.Enum`` was added.
|
Serialization support for ``enum.Enum`` was added.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.11
|
||||||
|
|
||||||
|
Serialization support for ``uuid.UUID`` was added.
|
||||||
|
|
||||||
Django can serialize the following on Python 3 only:
|
Django can serialize the following on Python 3 only:
|
||||||
|
|
||||||
- Unbound methods used from within the class body (see below)
|
- Unbound methods used from within the class body (see below)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import re
|
||||||
import sys
|
import sys
|
||||||
import tokenize
|
import tokenize
|
||||||
import unittest
|
import unittest
|
||||||
|
import uuid
|
||||||
|
|
||||||
import custom_migration_operations.more_operations
|
import custom_migration_operations.more_operations
|
||||||
import custom_migration_operations.operations
|
import custom_migration_operations.operations
|
||||||
|
@ -321,6 +322,31 @@ class WriterTests(SimpleTestCase):
|
||||||
"default=migrations.test_writer.IntEnum(1))"
|
"default=migrations.test_writer.IntEnum(1))"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_serialize_uuid(self):
|
||||||
|
self.assertSerializedEqual(uuid.uuid1())
|
||||||
|
self.assertSerializedEqual(uuid.uuid4())
|
||||||
|
|
||||||
|
uuid_a = uuid.UUID('5c859437-d061-4847-b3f7-e6b78852f8c8')
|
||||||
|
uuid_b = uuid.UUID('c7853ec1-2ea3-4359-b02d-b54e8f1bcee2')
|
||||||
|
self.assertSerializedResultEqual(
|
||||||
|
uuid_a,
|
||||||
|
("uuid.UUID('5c859437-d061-4847-b3f7-e6b78852f8c8')", {'import uuid'})
|
||||||
|
)
|
||||||
|
self.assertSerializedResultEqual(
|
||||||
|
uuid_b,
|
||||||
|
("uuid.UUID('c7853ec1-2ea3-4359-b02d-b54e8f1bcee2')", {'import uuid'})
|
||||||
|
)
|
||||||
|
|
||||||
|
field = models.UUIDField(choices=((uuid_a, 'UUID A'), (uuid_b, 'UUID B')), default=uuid_a)
|
||||||
|
string = MigrationWriter.serialize(field)[0]
|
||||||
|
self.assertEqual(
|
||||||
|
string,
|
||||||
|
"models.UUIDField(choices=["
|
||||||
|
"(uuid.UUID('5c859437-d061-4847-b3f7-e6b78852f8c8'), 'UUID A'), "
|
||||||
|
"(uuid.UUID('c7853ec1-2ea3-4359-b02d-b54e8f1bcee2'), 'UUID B')], "
|
||||||
|
"default=uuid.UUID('5c859437-d061-4847-b3f7-e6b78852f8c8'))"
|
||||||
|
)
|
||||||
|
|
||||||
def test_serialize_functions(self):
|
def test_serialize_functions(self):
|
||||||
with self.assertRaisesMessage(ValueError, 'Cannot serialize function: lambda'):
|
with self.assertRaisesMessage(ValueError, 'Cannot serialize function: lambda'):
|
||||||
self.assertSerializedEqual(lambda x: 42)
|
self.assertSerializedEqual(lambda x: 42)
|
||||||
|
|
Loading…
Reference in New Issue