فهرست منبع

Fixed #33916 -- Added support for serialization of enum.Flag in migrations.

Willem Van Onsem 2 سال پیش
والد
کامیت
16fffc829c
4فایلهای تغییر یافته به همراه29 افزوده شده و 4 حذف شده
  1. 15 2
      django/db/migrations/serializer.py
  2. 1 1
      docs/releases/4.2.txt
  3. 5 1
      docs/topics/migrations.txt
  4. 8 0
      tests/migrations/test_writer.py

+ 15 - 2
django/db/migrations/serializer.py

@@ -16,7 +16,7 @@ from django.db import models
 from django.db.migrations.operations.base import Operation
 from django.db.migrations.utils import COMPILED_REGEX_TYPE, RegexObject
 from django.utils.functional import LazyObject, Promise
-from django.utils.version import get_docs_version
+from django.utils.version import PY311, get_docs_version
 
 
 class BaseSerializer:
@@ -125,8 +125,21 @@ class EnumSerializer(BaseSerializer):
     def serialize(self):
         enum_class = self.value.__class__
         module = enum_class.__module__
+        if issubclass(enum_class, enum.Flag):
+            if PY311:
+                members = list(self.value)
+            else:
+                members, _ = enum._decompose(enum_class, self.value)
+                members = reversed(members)
+        else:
+            members = (self.value,)
         return (
-            "%s.%s[%r]" % (module, enum_class.__qualname__, self.value.name),
+            " | ".join(
+                [
+                    f"{module}.{enum_class.__qualname__}[{item.name!r}]"
+                    for item in members
+                ]
+            ),
             {"import %s" % module},
         )
 

+ 1 - 1
docs/releases/4.2.txt

@@ -192,7 +192,7 @@ Management Commands
 Migrations
 ~~~~~~~~~~
 
-* ...
+* Migrations now support serialization of ``enum.Flag`` objects.
 
 Models
 ~~~~~~

+ 5 - 1
docs/topics/migrations.txt

@@ -739,7 +739,7 @@ Django can serialize the following:
 - ``datetime.date``, ``datetime.time``, and ``datetime.datetime`` instances
   (include those that are timezone-aware)
 - ``decimal.Decimal`` instances
-- ``enum.Enum`` instances
+- ``enum.Enum``  and ``enum.Flag`` instances
 - ``uuid.UUID`` instances
 - :func:`functools.partial` and :class:`functools.partialmethod` instances
   which have serializable ``func``, ``args``, and ``keywords`` values.
@@ -756,6 +756,10 @@ Django can serialize the following:
 - Any class reference (must be in module's top-level scope)
 - Anything with a custom ``deconstruct()`` method (:ref:`see below <custom-deconstruct-method>`)
 
+.. versionchanged:: 4.2
+
+    Serialization support for ``enum.Flag`` was added.
+
 Django cannot serialize:
 
 - Nested classes

+ 8 - 0
tests/migrations/test_writer.py

@@ -413,6 +413,14 @@ class WriterTests(SimpleTestCase):
             "(2, migrations.test_writer.IntFlagEnum['B'])], "
             "default=migrations.test_writer.IntFlagEnum['A'])",
         )
+        self.assertSerializedResultEqual(
+            IntFlagEnum.A | IntFlagEnum.B,
+            (
+                "migrations.test_writer.IntFlagEnum['A'] | "
+                "migrations.test_writer.IntFlagEnum['B']",
+                {"import migrations.test_writer"},
+            ),
+        )
 
     def test_serialize_choices(self):
         class TextChoices(models.TextChoices):