瀏覽代碼

Ensure DocumentChooserBlock can be deconstructed for migrations

Fixes #8989. Now that DocumentChooserBlock is constructed dynamically via wagtail.documents.viewsets.chooser, we need to explicitly set its `__module__` attribute so that the result of calling `deconstruct()` for migrations points back to the wagtail.documents.blocks module.

Also update the documentation for defining custom choosers, and add tests for deconstructing the other chooser blocks.
Matt Westcott 2 年之前
父節點
當前提交
a6a94a9a04

+ 1 - 0
CHANGELOG.txt

@@ -163,6 +163,7 @@ Changelog
  * Fix: Layout issues with reports (including form submissions listings) on md device widths (Akash Kumar Sen, LB (Ben) Johnston)
  * Fix: Layout issue with page explorer's inner header item on small device widths (Akash Kumar Sen)
  * Fix: Ensure that `BaseSiteSetting` / `BaseGenericSetting` objects can be pickled (Andy Babic)
+ * Fix: Ensure `DocumentChooserBlock` can be deconstructed for migrations (Matt Westcott)
 
 
 3.0.1 (16.06.2022)

+ 4 - 0
docs/extending/generic_views.md

@@ -96,6 +96,10 @@ The viewset also makes a StreamField chooser block class available, as the prope
 from .views import person_chooser_viewset
 
 PersonChooserBlock = person_chooser_viewset.block_class
+
+# When deconstructing a PersonChooserBlock instance for migrations, the module path
+# used in migrations should point back to this module
+PersonChooserBlock.__module__ = "myapp.blocks"
 ```
 
 ## Chooser viewsets for non-model datasources

+ 1 - 0
docs/releases/4.0.md

@@ -220,6 +220,7 @@ The bulk of these enhancements have been from Paarth Agarwal, who has been doing
  * Resolve layout issues with reports (including form submissions listings) on md device widths (Akash Kumar Sen, LB (Ben) Johnston)
  * Resolve Layout issue with page explorer's inner header item on small device widths (Akash Kumar Sen)
  * Ensure that `BaseSiteSetting` / `BaseGenericSetting` objects can be pickled (Andy Babic)
+ * Ensure `DocumentChooserBlock` can be deconstructed for migrations (Matt Westcott)
 
 
 ## Upgrade considerations

+ 4 - 0
wagtail/documents/blocks.py

@@ -1,3 +1,7 @@
 from wagtail.documents.views.chooser import viewset as chooser_viewset
 
 DocumentChooserBlock = chooser_viewset.block_class
+
+# When deconstructing a DocumentChooserBlock instance for migrations, the module path
+# used in migrations should point to this module
+DocumentChooserBlock.__module__ = "wagtail.documents.blocks"

+ 12 - 0
wagtail/documents/tests/test_blocks.py

@@ -0,0 +1,12 @@
+from django.test import TestCase
+
+from wagtail.documents.blocks import DocumentChooserBlock
+
+
+class TestDocumentChooserBlock(TestCase):
+    def test_deconstruct(self):
+        block = DocumentChooserBlock(required=False)
+        path, args, kwargs = block.deconstruct()
+        self.assertEqual(path, "wagtail.documents.blocks.DocumentChooserBlock")
+        self.assertEqual(args, ())
+        self.assertEqual(kwargs, {"required": False})

+ 7 - 0
wagtail/images/tests/test_blocks.py

@@ -63,3 +63,10 @@ class TestImageChooserBlock(TestCase):
         )
 
         self.assertHTMLEqual(html, expected_html)
+
+    def test_deconstruct(self):
+        block = ImageChooserBlock(required=False)
+        path, args, kwargs = block.deconstruct()
+        self.assertEqual(path, "wagtail.images.blocks.ImageChooserBlock")
+        self.assertEqual(args, ())
+        self.assertEqual(kwargs, {"required": False})

+ 7 - 0
wagtail/snippets/tests/test_snippets.py

@@ -3174,6 +3174,13 @@ class TestSnippetChooserBlock(TestCase):
         self.assertEqual(nonrequired_block.clean(test_advert), test_advert)
         self.assertIsNone(nonrequired_block.clean(None))
 
+    def test_deconstruct(self):
+        block = SnippetChooserBlock(Advert, required=False)
+        path, args, kwargs = block.deconstruct()
+        self.assertEqual(path, "wagtail.snippets.blocks.SnippetChooserBlock")
+        self.assertEqual(args, (Advert,))
+        self.assertEqual(kwargs, {"required": False})
+
 
 class TestAdminSnippetChooserWidget(TestCase, WagtailTestUtils):
     def test_adapt(self):