Add PageChooserBlock target_model option

It allows selecting a restricted subset of pages, like with the
PageChooserPanel
pull/3072/merge
Tim Heap 2016-10-12 10:50:48 +11:00 zatwierdzone przez Matt Westcott
rodzic 4d8bfc1b2f
commit 9d54031a50
3 zmienionych plików z 43 dodań i 4 usunięć

Wyświetl plik

@ -242,6 +242,9 @@ A control for selecting a page object, using Wagtail's page browser. The followi
``required`` (default: True)
If true, the field cannot be left blank.
``target_model`` (default: Page)
Restrict choices to a single Page type.
``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

@ -13,6 +13,7 @@ from django.utils.html import format_html
from django.utils.safestring import mark_safe
from wagtail.wagtailcore.rich_text import RichText
from wagtail.wagtailcore.utils import resolve_model_string
from .base import Block
@ -530,19 +531,21 @@ class ChooserBlock(FieldBlock):
class PageChooserBlock(ChooserBlock):
def __init__(self, can_choose_root=False, **kwargs):
def __init__(self, target_model='wagtailcore.Page', can_choose_root=False,
**kwargs):
self._target_model = target_model
self.can_choose_root = can_choose_root
super(PageChooserBlock, self).__init__(**kwargs)
@cached_property
def target_model(self):
from wagtail.wagtailcore.models import Page # TODO: allow limiting to specific page types
return Page
return resolve_model_string(self._target_model)
@cached_property
def widget(self):
from wagtail.wagtailadmin.widgets import AdminPageChooser
return AdminPageChooser(can_choose_root=self.can_choose_root)
return AdminPageChooser(target_models=[self.target_model],
can_choose_root=self.can_choose_root)
def render_basic(self, value, context=None):
if value:
@ -550,6 +553,13 @@ class PageChooserBlock(ChooserBlock):
else:
return ''
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)
return name, args, kwargs
class Meta:
icon = "redirect"

Wyświetl plik

@ -20,6 +20,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.wagtailcore import blocks
from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore.rich_text import RichText
@ -2036,6 +2037,11 @@ 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):
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_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')
@ -2063,6 +2069,26 @@ class TestPageChooserBlock(TestCase):
self.assertEqual(nonrequired_block.clean(christmas_page), christmas_page)
self.assertEqual(nonrequired_block.clean(None), None)
def test_target_model_string(self):
block = blocks.PageChooserBlock(target_model='tests.SimplePage')
self.assertEqual(block.target_model, SimplePage)
def test_target_model_literal(self):
block = blocks.PageChooserBlock(target_model=SimplePage)
self.assertEqual(block.target_model, SimplePage)
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'}))
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'}))
class TestSystemCheck(TestCase):
def test_name_must_be_nonempty(self):