Commit 773387ce authored by Marten Kenbeek's avatar Marten Kenbeek Committed by Markus Holtermann
Browse files

[1.8.x] Fixed #24278 -- Fixed serialization of migration operations.

Fixed MigrationWriter.serialize() to correctly handle migration
operations by utilizing OperationWriter.

Thanks Piotr Maliński for the report.

Backport of e8e4f978 from master
parent 651cc369
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -437,6 +437,7 @@ answer newbie questions, and generally made Django that much better:
    Mark Lavin <markdlavin@gmail.com>
    Mark Sandstrom <mark@deliciouslynerdy.com>
    Markus Holtermann <https://markusholtermann.eu>
    Marten Kenbeek <marten.knbk+django@gmail.com>
    martin.glueck@gmail.com
    Martin Green
    Martin Kosír <martin@martinkosir.net>
+5 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ from importlib import import_module
from django.apps import apps
from django.db import migrations, models
from django.db.migrations.loader import MigrationLoader
from django.db.migrations.operations.base import Operation
from django.utils import datetime_safe, six
from django.utils._os import upath
from django.utils.encoding import force_text
@@ -395,6 +396,10 @@ class MigrationWriter(object):
                return "%s.as_manager()" % name, imports
            else:
                return cls.serialize_deconstructed(manager_path, args, kwargs)
        elif isinstance(value, Operation):
            string, imports = OperationWriter(value, indentation=0).serialize()
            # Nested operation, trailing comma is handled in upper OperationWriter._write()
            return string.rstrip(','), imports
        # Anything that knows how to deconstruct itself.
        elif hasattr(value, 'deconstruct'):
            return cls.serialize_deconstructed(*value.deconstruct())
+4 −0
Original line number Diff line number Diff line
@@ -17,3 +17,7 @@ Bugfixes

* Prevented ``TypeError`` in translation functions ``check_for_language()`` and
  ``get_language_bidi()`` when translations are deactivated (:ticket:`24569`).

* Fixed :djadmin:`squashmigrations` command when using
  :class:`~django.db.migrations.operations.SeparateDatabaseAndState`
  (:ticket:`24278`).
+44 −0
Original line number Diff line number Diff line
@@ -81,6 +81,27 @@ class OperationWriterTests(SimpleTestCase):
            '),'
        )

    def test_nested_args_signature(self):
        operation = custom_migration_operations.operations.ArgsOperation(
            custom_migration_operations.operations.ArgsOperation(1, 2),
            custom_migration_operations.operations.KwargsOperation(kwarg1=3, kwarg2=4)
        )
        buff, imports = OperationWriter(operation, indentation=0).serialize()
        self.assertEqual(imports, {'import custom_migration_operations.operations'})
        self.assertEqual(
            buff,
            'custom_migration_operations.operations.ArgsOperation(\n'
            '    arg1=custom_migration_operations.operations.ArgsOperation(\n'
            '        arg1=1,\n'
            '        arg2=2,\n'
            '    ),\n'
            '    arg2=custom_migration_operations.operations.KwargsOperation(\n'
            '        kwarg1=3,\n'
            '        kwarg2=4,\n'
            '    ),\n'
            '),'
        )

    def test_multiline_args_signature(self):
        operation = custom_migration_operations.operations.ArgsOperation("test\n    arg1", "test\narg2")
        buff, imports = OperationWriter(operation, indentation=0).serialize()
@@ -107,6 +128,29 @@ class OperationWriterTests(SimpleTestCase):
            '),'
        )

    def test_nested_operation_expand_args_signature(self):
        operation = custom_migration_operations.operations.ExpandArgsOperation(
            arg=[
                custom_migration_operations.operations.KwargsOperation(
                    kwarg1=1,
                    kwarg2=2,
                ),
            ]
        )
        buff, imports = OperationWriter(operation, indentation=0).serialize()
        self.assertEqual(imports, {'import custom_migration_operations.operations'})
        self.assertEqual(
            buff,
            'custom_migration_operations.operations.ExpandArgsOperation(\n'
            '    arg=[\n'
            '        custom_migration_operations.operations.KwargsOperation(\n'
            '            kwarg1=1,\n'
            '            kwarg2=2,\n'
            '        ),\n'
            '    ],\n'
            '),'
        )


class WriterTests(TestCase):
    """