kopia lustrzana https://github.com/wagtail/wagtail
rodzic
e77da0a1a1
commit
c606e3f722
|
@ -225,7 +225,7 @@ class StreamField(Field):
|
|||
foreign objects are nested objects with id and meta as attributes.
|
||||
"""
|
||||
def to_representation(self, value):
|
||||
return value.stream_block.get_prep_value(value)
|
||||
return value.stream_block.get_api_representation(value, self.context)
|
||||
|
||||
|
||||
class TagsField(Field):
|
||||
|
|
|
@ -1025,6 +1025,18 @@ class TestPageDetailWithStreamField(TestCase):
|
|||
# ForeignKeys in a StreamField shouldn't be translated into dictionary representation
|
||||
self.assertEqual(content['body'], [{'type': 'image', 'value': 1}])
|
||||
|
||||
def test_image_block_with_custom_get_api_representation(self):
|
||||
stream_page = self.make_stream_page('[{"type": "image", "value": 1}]')
|
||||
|
||||
response_url = '{}?extended=1'.format(
|
||||
reverse('wagtailapi_v2:pages:detail', args=(stream_page.id, ))
|
||||
)
|
||||
response = self.client.get(response_url)
|
||||
content = json.loads(response.content.decode('utf-8'))
|
||||
|
||||
# the custom get_api_representation returns a dict of id and title for the image
|
||||
self.assertEqual(content['body'], [{'type': 'image', 'value': {'id': 1, 'title': 'A missing image'}}])
|
||||
|
||||
|
||||
@override_settings(
|
||||
WAGTAILFRONTENDCACHE={
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.4 on 2016-12-20 10:57
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
import wagtail.tests.testapp.models
|
||||
import wagtail.wagtailcore.blocks
|
||||
import wagtail.wagtailcore.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tests', '0012_panelsettings_tabbedsettings'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='streampage',
|
||||
name='body',
|
||||
field=wagtail.wagtailcore.fields.StreamField([('text', wagtail.wagtailcore.blocks.CharBlock()), ('rich_text', wagtail.wagtailcore.blocks.RichTextBlock()), ('image', wagtail.tests.testapp.models.ExtendedImageChooserBlock())]),
|
||||
),
|
||||
]
|
|
@ -638,11 +638,27 @@ class StreamModel(models.Model):
|
|||
])
|
||||
|
||||
|
||||
class ExtendedImageChooserBlock(ImageChooserBlock):
|
||||
"""
|
||||
Example of Block with custom get_api_representation method.
|
||||
If the request has an 'extended' query param, it returns a dict of id and title,
|
||||
otherwise, it returns the default value.
|
||||
"""
|
||||
def get_api_representation(self, value, context=None):
|
||||
image_id = super(ExtendedImageChooserBlock, self).get_api_representation(value, context=context)
|
||||
if 'request' in context and context['request'].query_params.get('extended', False):
|
||||
return {
|
||||
'id': image_id,
|
||||
'title': value.title
|
||||
}
|
||||
return image_id
|
||||
|
||||
|
||||
class StreamPage(Page):
|
||||
body = StreamField([
|
||||
('text', CharBlock()),
|
||||
('rich_text', RichTextBlock()),
|
||||
('image', ImageChooserBlock()),
|
||||
('image', ExtendedImageChooserBlock()),
|
||||
])
|
||||
|
||||
api_fields = ('body',)
|
||||
|
|
|
@ -257,6 +257,12 @@ class Block(six.with_metaclass(BaseBlock, object)):
|
|||
|
||||
return mark_safe(render_to_string(template, new_context))
|
||||
|
||||
def get_api_representation(self, value, context=None):
|
||||
"""
|
||||
Can be used to customise the API response and defaults to the value returned by get_prep_value.
|
||||
"""
|
||||
return self.get_prep_value(value)
|
||||
|
||||
def render_basic(self, value, context=None):
|
||||
"""
|
||||
Return a text rendering of 'value', suitable for display on templates. render() will fall back on
|
||||
|
|
|
@ -143,6 +143,13 @@ class ListBlock(Block):
|
|||
for item in value
|
||||
]
|
||||
|
||||
def get_api_representation(self, value, context=None):
|
||||
# recursively call get_api_representation on children and return as a list
|
||||
return [
|
||||
self.child_block.get_api_representation(item, context=context)
|
||||
for item in value
|
||||
]
|
||||
|
||||
def render_basic(self, value, context=None):
|
||||
children = format_html_join(
|
||||
'\n', '<li>{0}</li>',
|
||||
|
|
|
@ -211,6 +211,16 @@ class BaseStreamBlock(Block):
|
|||
for child in value # child is a BoundBlock instance
|
||||
]
|
||||
|
||||
def get_api_representation(self, value, context=None):
|
||||
if value is None:
|
||||
# treat None as identical to an empty stream
|
||||
return []
|
||||
|
||||
return [
|
||||
{'type': child.block.name, 'value': child.block.get_api_representation(child.value, context=context)}
|
||||
for child in value # child is a BoundBlock instance
|
||||
]
|
||||
|
||||
def render_basic(self, value, context=None):
|
||||
return format_html_join(
|
||||
'\n', '<div class="block-{1}">{0}</div>',
|
||||
|
|
|
@ -138,6 +138,13 @@ class BaseStructBlock(Block):
|
|||
for name, val in value.items()
|
||||
])
|
||||
|
||||
def get_api_representation(self, value, context=None):
|
||||
# recursively call get_api_representation on children and return as a plain dict
|
||||
return dict([
|
||||
(name, self.child_blocks[name].get_api_representation(val, context=context))
|
||||
for name, val in value.items()
|
||||
])
|
||||
|
||||
def get_searchable_content(self, value):
|
||||
content = []
|
||||
|
||||
|
|
|
@ -961,6 +961,39 @@ class TestStructBlock(SimpleTestCase):
|
|||
|
||||
self.assertHTMLEqual(html, expected_html)
|
||||
|
||||
def test_get_api_representation_calls_same_method_on_fields_with_context(self):
|
||||
"""
|
||||
The get_api_representation method of a StructBlock should invoke
|
||||
the block's get_api_representation method on each field and the
|
||||
context should be passed on.
|
||||
"""
|
||||
class ContextBlock(blocks.CharBlock):
|
||||
def get_api_representation(self, value, context=None):
|
||||
return context[value]
|
||||
|
||||
class AuthorBlock(blocks.StructBlock):
|
||||
language = ContextBlock()
|
||||
author = ContextBlock()
|
||||
|
||||
block = AuthorBlock()
|
||||
api_representation = block.get_api_representation(
|
||||
{
|
||||
'language': 'en',
|
||||
'author': 'wagtail',
|
||||
},
|
||||
context={
|
||||
'en': 'English',
|
||||
'wagtail': 'Wagtail!'
|
||||
}
|
||||
)
|
||||
|
||||
self.assertDictEqual(
|
||||
api_representation, {
|
||||
'language': 'English',
|
||||
'author': 'Wagtail!'
|
||||
}
|
||||
)
|
||||
|
||||
def test_render_unknown_field(self):
|
||||
class LinkBlock(blocks.StructBlock):
|
||||
title = blocks.CharBlock()
|
||||
|
@ -1334,6 +1367,28 @@ class TestListBlock(unittest.TestCase):
|
|||
self.assertIn('<h1 lang="fr">Bonjour le monde!</h1>', html)
|
||||
self.assertIn('<h1 lang="fr">Au revoir le monde!</h1>', html)
|
||||
|
||||
def test_get_api_representation_calls_same_method_on_children_with_context(self):
|
||||
"""
|
||||
The get_api_representation method of a ListBlock should invoke
|
||||
the block's get_api_representation method on each child and
|
||||
the context should be passed on.
|
||||
"""
|
||||
class ContextBlock(blocks.CharBlock):
|
||||
def get_api_representation(self, value, context=None):
|
||||
return context[value]
|
||||
|
||||
block = blocks.ListBlock(
|
||||
ContextBlock()
|
||||
)
|
||||
api_representation = block.get_api_representation(["en", "fr"], context={
|
||||
'en': 'Hello world!',
|
||||
'fr': 'Bonjour le monde!'
|
||||
})
|
||||
|
||||
self.assertEqual(
|
||||
api_representation, ['Hello world!', 'Bonjour le monde!']
|
||||
)
|
||||
|
||||
def render_form(self):
|
||||
class LinkBlock(blocks.StructBlock):
|
||||
title = blocks.CharBlock()
|
||||
|
@ -1652,6 +1707,38 @@ class TestStreamBlock(SimpleTestCase):
|
|||
|
||||
return block.render(value)
|
||||
|
||||
def test_get_api_representation_calls_same_method_on_children_with_context(self):
|
||||
"""
|
||||
The get_api_representation method of a StreamBlock should invoke
|
||||
the block's get_api_representation method on each child and
|
||||
the context should be passed on.
|
||||
"""
|
||||
class ContextBlock(blocks.CharBlock):
|
||||
def get_api_representation(self, value, context=None):
|
||||
return context[value]
|
||||
|
||||
block = blocks.StreamBlock([
|
||||
('language', ContextBlock()),
|
||||
('author', ContextBlock()),
|
||||
])
|
||||
api_representation = block.get_api_representation(
|
||||
block.to_python([
|
||||
{'type': 'language', 'value': 'en'},
|
||||
{'type': 'author', 'value': 'wagtail'},
|
||||
]),
|
||||
context={
|
||||
'en': 'English',
|
||||
'wagtail': 'Wagtail!'
|
||||
}
|
||||
)
|
||||
|
||||
self.assertListEqual(
|
||||
api_representation, [
|
||||
{'type': 'language', 'value': 'English'},
|
||||
{'type': 'author', 'value': 'Wagtail!'},
|
||||
]
|
||||
)
|
||||
|
||||
def test_render(self):
|
||||
html = self.render_article([
|
||||
{
|
||||
|
|
Ładowanie…
Reference in New Issue