Enhancement for PageChooserBlock

Allow the target_model argument to be a list or tuple.
pull/3382/head
Mikalai Radchuk 2017-01-24 20:03:21 +03:00 zatwierdzone przez Matt Westcott
rodzic 46c9cdda15
commit eb47526888
5 zmienionych plików z 100 dodań i 11 usunięć

Wyświetl plik

@ -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))

Wyświetl plik

@ -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

Wyświetl plik

@ -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'.

Wyświetl plik

@ -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:

Wyświetl plik

@ -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):