kopia lustrzana https://github.com/wagtail/wagtail
Enhancement for PageChooserBlock
Allow the target_model argument to be a list or tuple.pull/3382/head
rodzic
46c9cdda15
commit
eb47526888
|
@ -10,6 +10,7 @@ Changelog
|
|||
* Added `construct_image_chooser_queryset`, `construct_document_chooser_queryset` and `construct_page_chooser_queryset` hooks (Gagaro)
|
||||
* The homepage created in the project template is now titled "Home" rather than "Homepage" (Karl Hobley)
|
||||
* Signal receivers for custom `Image` and `Rendition` models are connected automatically (Mike Dingjan)
|
||||
* `PageChooserBlock` can now accept a list/tuple of page models as `target_model` (Mikalai Radchuk)
|
||||
* Fix: Marked 'Date from' / 'Date to' strings in wagtailforms for translation (Vorlif)
|
||||
* Fix: Unreliable preview is now reliable by always opening in a new window (Kjartan Sverrisson)
|
||||
* Fix: Fixed placement of `{{ block.super }}` in `snippets/type_index.html` (LB (Ben Johnston))
|
||||
|
|
|
@ -20,6 +20,7 @@ Other features
|
|||
* Added ``construct_image_chooser_queryset``, ``construct_document_chooser_queryset`` and ``construct_page_chooser_queryset`` hooks (Gagaro)
|
||||
* The homepage created in the project template is now titled "Home" rather than "Homepage" (Karl Hobley)
|
||||
* Signal receivers for custom ``Image`` and ``Rendition`` models are connected automatically (Mike Dingjan)
|
||||
* ``PageChooserBlock`` can now accept a list/tuple of page models as ``target_model`` (Mikalai Radchuk)
|
||||
|
||||
|
||||
Bug fixes
|
||||
|
|
|
@ -251,7 +251,7 @@ A control for selecting a page object, using Wagtail's page browser. The followi
|
|||
If true, the field cannot be left blank.
|
||||
|
||||
``target_model`` (default: Page)
|
||||
Restrict choices to a single Page type.
|
||||
Restrict choices to one or more specific page types. Accepts a page model class, model name (as a string), or a list or tuple of these.
|
||||
|
||||
``can_choose_root`` (default: False)
|
||||
If true, the editor can choose the tree root as a page. Normally this would be undesirable, since the tree root is never a usable page, but in some specialised cases it may be appropriate. For example, a block providing a feed of related articles could use a PageChooserBlock to select which subsection of the site articles will be taken from, with the root corresponding to 'everywhere'.
|
||||
|
|
|
@ -581,20 +581,48 @@ class ChooserBlock(FieldBlock):
|
|||
|
||||
class PageChooserBlock(ChooserBlock):
|
||||
|
||||
def __init__(self, target_model='wagtailcore.Page', can_choose_root=False,
|
||||
# TODO: rename target_model to page_type
|
||||
def __init__(self, target_model=None, can_choose_root=False,
|
||||
**kwargs):
|
||||
self._target_model = target_model
|
||||
if target_model:
|
||||
# Convert single string/model into a list
|
||||
if not isinstance(target_model, (list, tuple)):
|
||||
target_model = [target_model]
|
||||
else:
|
||||
target_model = []
|
||||
|
||||
self._target_models = target_model
|
||||
self.can_choose_root = can_choose_root
|
||||
super(PageChooserBlock, self).__init__(**kwargs)
|
||||
|
||||
@cached_property
|
||||
def target_model(self):
|
||||
return resolve_model_string(self._target_model)
|
||||
"""
|
||||
Defines the model used by the base ChooserBlock for ID <-> instance
|
||||
conversions. If a single page type is specified in target_model,
|
||||
we can use that to get the more specific instance "for free"; otherwise
|
||||
use the generic Page model.
|
||||
"""
|
||||
if len(self.target_models) == 1:
|
||||
return self.target_models[0]
|
||||
|
||||
return resolve_model_string('wagtailcore.Page')
|
||||
|
||||
@cached_property
|
||||
def target_models(self):
|
||||
target_models = []
|
||||
|
||||
for target_model in self._target_models:
|
||||
target_models.append(
|
||||
resolve_model_string(target_model)
|
||||
)
|
||||
|
||||
return target_models
|
||||
|
||||
@cached_property
|
||||
def widget(self):
|
||||
from wagtail.wagtailadmin.widgets import AdminPageChooser
|
||||
return AdminPageChooser(target_models=[self.target_model],
|
||||
return AdminPageChooser(target_models=self.target_models,
|
||||
can_choose_root=self.can_choose_root)
|
||||
|
||||
def render_basic(self, value, context=None):
|
||||
|
@ -605,9 +633,18 @@ class PageChooserBlock(ChooserBlock):
|
|||
|
||||
def deconstruct(self):
|
||||
name, args, kwargs = super(PageChooserBlock, self).deconstruct()
|
||||
|
||||
if 'target_model' in kwargs:
|
||||
opts = self.target_model._meta
|
||||
kwargs['target_model'] = '{}.{}'.format(opts.app_label, opts.object_name)
|
||||
target_models = []
|
||||
|
||||
for target_model in self.target_models:
|
||||
opts = target_model._meta
|
||||
target_models.append(
|
||||
'{}.{}'.format(opts.app_label, opts.object_name)
|
||||
)
|
||||
|
||||
kwargs['target_model'] = target_models
|
||||
|
||||
return name, args, kwargs
|
||||
|
||||
class Meta:
|
||||
|
|
|
@ -21,7 +21,7 @@ from django.utils.translation import ugettext_lazy as __
|
|||
|
||||
from wagtail.tests.testapp.blocks import LinkBlock as CustomLinkBlock
|
||||
from wagtail.tests.testapp.blocks import SectionBlock
|
||||
from wagtail.tests.testapp.models import SimplePage
|
||||
from wagtail.tests.testapp.models import EventPage, SimplePage
|
||||
from wagtail.utils.deprecation import RemovedInWagtail111Warning
|
||||
from wagtail.wagtailcore import blocks
|
||||
from wagtail.wagtailcore.models import Page
|
||||
|
@ -2265,11 +2265,31 @@ class TestPageChooserBlock(TestCase):
|
|||
self.assertIn(expected_html, christmas_form_html)
|
||||
self.assertIn("pick a page, any page", christmas_form_html)
|
||||
|
||||
def test_form_render_with_target_model(self):
|
||||
def test_form_render_with_target_model_default(self):
|
||||
block = blocks.PageChooserBlock()
|
||||
empty_form_html = block.render_form(None, 'page')
|
||||
self.assertIn('createPageChooser("page", ["wagtailcore.page"], null, false);', empty_form_html)
|
||||
|
||||
def test_form_render_with_target_model_string(self):
|
||||
block = blocks.PageChooserBlock(help_text="pick a page, any page", target_model='tests.SimplePage')
|
||||
empty_form_html = block.render_form(None, 'page')
|
||||
self.assertIn('createPageChooser("page", ["tests.simplepage"], null, false);', empty_form_html)
|
||||
|
||||
def test_form_render_with_target_model_literal(self):
|
||||
block = blocks.PageChooserBlock(help_text="pick a page, any page", target_model=SimplePage)
|
||||
empty_form_html = block.render_form(None, 'page')
|
||||
self.assertIn('createPageChooser("page", ["tests.simplepage"], null, false);', empty_form_html)
|
||||
|
||||
def test_form_render_with_target_model_multiple_strings(self):
|
||||
block = blocks.PageChooserBlock(help_text="pick a page, any page", target_model=['tests.SimplePage', 'tests.EventPage'])
|
||||
empty_form_html = block.render_form(None, 'page')
|
||||
self.assertIn('createPageChooser("page", ["tests.simplepage", "tests.eventpage"], null, false);', empty_form_html)
|
||||
|
||||
def test_form_render_with_target_model_multiple_literals(self):
|
||||
block = blocks.PageChooserBlock(help_text="pick a page, any page", target_model=[SimplePage, EventPage])
|
||||
empty_form_html = block.render_form(None, 'page')
|
||||
self.assertIn('createPageChooser("page", ["tests.simplepage", "tests.eventpage"], null, false);', empty_form_html)
|
||||
|
||||
def test_form_render_with_can_choose_root(self):
|
||||
block = blocks.PageChooserBlock(help_text="pick a page, any page", can_choose_root=True)
|
||||
empty_form_html = block.render_form(None, 'page')
|
||||
|
@ -2297,6 +2317,10 @@ class TestPageChooserBlock(TestCase):
|
|||
self.assertEqual(nonrequired_block.clean(christmas_page), christmas_page)
|
||||
self.assertEqual(nonrequired_block.clean(None), None)
|
||||
|
||||
def test_target_model_default(self):
|
||||
block = blocks.PageChooserBlock()
|
||||
self.assertEqual(block.target_model, Page)
|
||||
|
||||
def test_target_model_string(self):
|
||||
block = blocks.PageChooserBlock(target_model='tests.SimplePage')
|
||||
self.assertEqual(block.target_model, SimplePage)
|
||||
|
@ -2305,17 +2329,43 @@ class TestPageChooserBlock(TestCase):
|
|||
block = blocks.PageChooserBlock(target_model=SimplePage)
|
||||
self.assertEqual(block.target_model, SimplePage)
|
||||
|
||||
def test_target_model_multiple_strings(self):
|
||||
block = blocks.PageChooserBlock(target_model=['tests.SimplePage', 'tests.EventPage'])
|
||||
self.assertEqual(block.target_model, Page)
|
||||
|
||||
def test_target_model_multiple_literals(self):
|
||||
block = blocks.PageChooserBlock(target_model=[SimplePage, EventPage])
|
||||
self.assertEqual(block.target_model, Page)
|
||||
|
||||
def test_deconstruct_target_model_default(self):
|
||||
block = blocks.PageChooserBlock()
|
||||
self.assertEqual(block.deconstruct(), (
|
||||
'wagtail.wagtailcore.blocks.PageChooserBlock',
|
||||
(), {}))
|
||||
|
||||
def test_deconstruct_target_model_string(self):
|
||||
block = blocks.PageChooserBlock(target_model='tests.SimplePage')
|
||||
self.assertEqual(block.deconstruct(), (
|
||||
'wagtail.wagtailcore.blocks.PageChooserBlock',
|
||||
(), {'target_model': 'tests.SimplePage'}))
|
||||
(), {'target_model': ['tests.SimplePage']}))
|
||||
|
||||
def test_deconstruct_target_model_literal(self):
|
||||
block = blocks.PageChooserBlock(target_model=SimplePage)
|
||||
self.assertEqual(block.deconstruct(), (
|
||||
'wagtail.wagtailcore.blocks.PageChooserBlock',
|
||||
(), {'target_model': 'tests.SimplePage'}))
|
||||
(), {'target_model': ['tests.SimplePage']}))
|
||||
|
||||
def test_deconstruct_target_model_multiple_strings(self):
|
||||
block = blocks.PageChooserBlock(target_model=['tests.SimplePage', 'tests.EventPage'])
|
||||
self.assertEqual(block.deconstruct(), (
|
||||
'wagtail.wagtailcore.blocks.PageChooserBlock',
|
||||
(), {'target_model': ['tests.SimplePage', 'tests.EventPage']}))
|
||||
|
||||
def test_deconstruct_target_model_multiple_literals(self):
|
||||
block = blocks.PageChooserBlock(target_model=[SimplePage, EventPage])
|
||||
self.assertEqual(block.deconstruct(), (
|
||||
'wagtail.wagtailcore.blocks.PageChooserBlock',
|
||||
(), {'target_model': ['tests.SimplePage', 'tests.EventPage']}))
|
||||
|
||||
|
||||
class TestStaticBlock(unittest.TestCase):
|
||||
|
|
Ładowanie…
Reference in New Issue