diff --git a/django/db/migrations/operations/special.py b/django/db/migrations/operations/special.py
index 2c995c54ac..e1ce9a07b5 100644
--- a/django/db/migrations/operations/special.py
+++ b/django/db/migrations/operations/special.py
@@ -13,6 +13,8 @@ class SeparateDatabaseAndState(Operation):
     that affect the state or not the database, or so on.
     """
 
+    serialization_expand_args = ['database_operations', 'state_operations']
+
     def __init__(self, database_operations=None, state_operations=None):
         self.database_operations = database_operations or []
         self.state_operations = state_operations or []
diff --git a/django/db/migrations/writer.py b/django/db/migrations/writer.py
index 99db9d18ae..83cea065ab 100644
--- a/django/db/migrations/writer.py
+++ b/django/db/migrations/writer.py
@@ -39,11 +39,10 @@ class SettingsReference(str):
 
 
 class OperationWriter(object):
-    indentation = 2
-
-    def __init__(self, operation):
+    def __init__(self, operation, indentation=2):
         self.operation = operation
         self.buff = []
+        self.indentation = indentation
 
     def serialize(self):
 
@@ -56,7 +55,14 @@ class OperationWriter(object):
                     for key, value in _arg_value.items():
                         key_string, key_imports = MigrationWriter.serialize(key)
                         arg_string, arg_imports = MigrationWriter.serialize(value)
-                        self.feed('%s: %s,' % (key_string, arg_string))
+                        args = arg_string.splitlines()
+                        if len(args) > 1:
+                            self.feed('%s: %s' % (key_string, args[0]))
+                            for arg in args[1:-1]:
+                                self.feed(arg)
+                            self.feed('%s,' % args[-1])
+                        else:
+                            self.feed('%s: %s,' % (key_string, arg_string))
                         imports.update(key_imports)
                         imports.update(arg_imports)
                     self.unindent()
@@ -66,13 +72,26 @@ class OperationWriter(object):
                     self.indent()
                     for item in _arg_value:
                         arg_string, arg_imports = MigrationWriter.serialize(item)
-                        self.feed('%s,' % arg_string)
+                        args = arg_string.splitlines()
+                        if len(args) > 1:
+                            for arg in args[:-1]:
+                                self.feed(arg)
+                            self.feed('%s,' % args[-1])
+                        else:
+                            self.feed('%s,' % arg_string)
                         imports.update(arg_imports)
                     self.unindent()
                     self.feed('],')
             else:
                 arg_string, arg_imports = MigrationWriter.serialize(_arg_value)
-                self.feed('%s=%s,' % (_arg_name, arg_string))
+                args = arg_string.splitlines()
+                if len(args) > 1:
+                    self.feed('%s=%s' % (_arg_name, args[0]))
+                    for arg in args[1:-1]:
+                        self.feed(arg)
+                    self.feed('%s,' % args[-1])
+                else:
+                    self.feed('%s=%s,' % (_arg_name, arg_string))
                 imports.update(arg_imports)
 
         imports = set()
diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py
index d2bd491635..bbe81ad58d 100644
--- a/tests/migrations/test_writer.py
+++ b/tests/migrations/test_writer.py
@@ -37,9 +37,7 @@ class OperationWriterTests(SimpleTestCase):
 
     def test_empty_signature(self):
         operation = custom_migration_operations.operations.TestOperation()
-        writer = OperationWriter(operation)
-        writer.indentation = 0
-        buff, imports = writer.serialize()
+        buff, imports = OperationWriter(operation, indentation=0).serialize()
         self.assertEqual(imports, {'import custom_migration_operations.operations'})
         self.assertEqual(
             buff,
@@ -49,9 +47,7 @@ class OperationWriterTests(SimpleTestCase):
 
     def test_args_signature(self):
         operation = custom_migration_operations.operations.ArgsOperation(1, 2)
-        writer = OperationWriter(operation)
-        writer.indentation = 0
-        buff, imports = writer.serialize()
+        buff, imports = OperationWriter(operation, indentation=0).serialize()
         self.assertEqual(imports, {'import custom_migration_operations.operations'})
         self.assertEqual(
             buff,
@@ -63,9 +59,7 @@ class OperationWriterTests(SimpleTestCase):
 
     def test_kwargs_signature(self):
         operation = custom_migration_operations.operations.KwargsOperation(kwarg1=1)
-        writer = OperationWriter(operation)
-        writer.indentation = 0
-        buff, imports = writer.serialize()
+        buff, imports = OperationWriter(operation, indentation=0).serialize()
         self.assertEqual(imports, {'import custom_migration_operations.operations'})
         self.assertEqual(
             buff,
@@ -76,9 +70,7 @@ class OperationWriterTests(SimpleTestCase):
 
     def test_args_kwargs_signature(self):
         operation = custom_migration_operations.operations.ArgsKwargsOperation(1, 2, kwarg2=4)
-        writer = OperationWriter(operation)
-        writer.indentation = 0
-        buff, imports = writer.serialize()
+        buff, imports = OperationWriter(operation, indentation=0).serialize()
         self.assertEqual(imports, {'import custom_migration_operations.operations'})
         self.assertEqual(
             buff,
@@ -89,11 +81,21 @@ class OperationWriterTests(SimpleTestCase):
             '),'
         )
 
+    def test_multiline_args_signature(self):
+        operation = custom_migration_operations.operations.ArgsOperation("test\n    arg1", "test\narg2")
+        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='test\\n    arg1',\n"
+            "    arg2='test\\narg2',\n"
+            "),"
+        )
+
     def test_expand_args_signature(self):
         operation = custom_migration_operations.operations.ExpandArgsOperation([1, 2])
-        writer = OperationWriter(operation)
-        writer.indentation = 0
-        buff, imports = writer.serialize()
+        buff, imports = OperationWriter(operation, indentation=0).serialize()
         self.assertEqual(imports, {'import custom_migration_operations.operations'})
         self.assertEqual(
             buff,
@@ -159,6 +161,14 @@ class WriterTests(TestCase):
         string, imports = MigrationWriter.serialize("foobar")
         self.assertEqual(string, "'foobar'")
 
+    def test_serialize_multiline_strings(self):
+        self.assertSerializedEqual(b"foo\nbar")
+        string, imports = MigrationWriter.serialize(b"foo\nbar")
+        self.assertEqual(string, "b'foo\\nbar'")
+        self.assertSerializedEqual("föo\nbár")
+        string, imports = MigrationWriter.serialize("foo\nbar")
+        self.assertEqual(string, "'foo\\nbar'")
+
     def test_serialize_collections(self):
         self.assertSerializedEqual({1: 2})
         self.assertSerializedEqual(["a", 2, True, None])