kopia lustrzana https://github.com/wagtail/wagtail
Allow ListBlocks to leverage child bulk_to_python
Currently a select set of StreamField blocks like PageChooserBlock expose a bulk_to_python method that is used to optimize their retrieval from the database. As reported in issue 5926, ListBlock could take advantage of this so that its child items are loaded at once, instead of one at a time. This change modifies how ListBlock.to_python works so that it calls its child block's bulk_to_python, if defined. This allows for a single query instead of one query per child item. Note that this change doesn't add bulk_to_python to ListBlock itself, meaning that individual ListBlocks in a StreamField or StructBlock are still retrieved independently. But it does optimize the lookup for each ListBlock.pull/5931/head
rodzic
bb2e460c0b
commit
3797132b4d
|
@ -22,6 +22,7 @@ Changelog
|
|||
* Optimise compiling media definitions for complex StreamBlocks (pimarc)
|
||||
* FieldPanel now accepts a 'heading' argument (Jacob Topp-Mugglestone)
|
||||
* Replaced deprecated `ugettext` / `ungettext` calls with `gettext` / `ngettext` (Mohamed Feddad)
|
||||
* ListBlocks now call child block `bulk_to_python` if defined (Andy Chosak)
|
||||
* Fix: Added ARIA alert role to live search forms in the admin (Casper Timmers)
|
||||
* Fix: Reorder login form elements to match expected tab order (Kjartan Sverrisson)
|
||||
* Fix: Re-add 'Close Explorer' button on mobile viewports (Sævar Öfjörð Magnússon)
|
||||
|
|
|
@ -35,6 +35,7 @@ Other features
|
|||
* Optimise compiling media definitions for complex StreamBlocks (pimarc)
|
||||
* FieldPanel now accepts a 'heading' argument (Jacob Topp-Mugglestone)
|
||||
* Replaced deprecated ``ugettext`` / ``ungettext`` calls with ``gettext`` / ``ngettext`` (Mohamed Feddad)
|
||||
* ListBLocks now call child block ``bulk_to_python`` if defined (Andy Chosak)
|
||||
|
||||
|
||||
Bug fixes
|
||||
|
|
|
@ -132,7 +132,11 @@ class ListBlock(Block):
|
|||
return result
|
||||
|
||||
def to_python(self, value):
|
||||
# recursively call to_python on children and return as a list
|
||||
# If child block supports bulk retrieval, use it.
|
||||
if hasattr(self.child_block, 'bulk_to_python'):
|
||||
return self.child_block.bulk_to_python(value)
|
||||
|
||||
# Otherwise recursively call to_python on each child and return as a list.
|
||||
return [
|
||||
self.child_block.to_python(item)
|
||||
for item in value
|
||||
|
|
|
@ -2260,6 +2260,20 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase):
|
|||
self.assertIn('value="chocolate"', form_html)
|
||||
|
||||
|
||||
class TestListBlockWithFixtures(TestCase):
|
||||
fixtures = ['test.json']
|
||||
|
||||
def test_calls_child_bulk_to_python_when_available(self):
|
||||
page_ids = [2, 3, 4, 5]
|
||||
expected_pages = Page.objects.filter(pk__in=page_ids)
|
||||
block = blocks.ListBlock(blocks.PageChooserBlock())
|
||||
|
||||
with self.assertNumQueries(1):
|
||||
pages = block.to_python(page_ids)
|
||||
|
||||
self.assertSequenceEqual(pages, expected_pages)
|
||||
|
||||
|
||||
class TestStreamBlock(WagtailTestUtils, SimpleTestCase):
|
||||
def test_initialisation(self):
|
||||
block = blocks.StreamBlock([
|
||||
|
@ -3275,6 +3289,16 @@ class TestPageChooserBlock(TestCase):
|
|||
'wagtail.core.blocks.PageChooserBlock',
|
||||
(), {'page_type': ['tests.SimplePage', 'tests.EventPage']}))
|
||||
|
||||
def test_bulk_to_python(self):
|
||||
page_ids = [2, 3, 4, 5]
|
||||
expected_pages = Page.objects.filter(pk__in=page_ids)
|
||||
block = blocks.PageChooserBlock()
|
||||
|
||||
with self.assertNumQueries(1):
|
||||
pages = block.bulk_to_python(page_ids)
|
||||
|
||||
self.assertSequenceEqual(pages, expected_pages)
|
||||
|
||||
|
||||
class TestStaticBlock(unittest.TestCase):
|
||||
def test_render_form_with_constructor(self):
|
||||
|
|
Ładowanie…
Reference in New Issue