Как отобразить атрибуты страницы в модели при отображении в StreamField?

У меня есть следующая StructBlock и Page модель:

class PostGrid(blocks.StructBlock):
    title = blocks.CharBlock()
    post_1 = blocks.PageChooserBlock()
    post_2 = blocks.PageChooserBlock()

    class Meta:
        template = 'post-grid.html'

class BlogIndex(Page):
    body = StreamField([('POSTS', PostGrid()),])

    class Meta:
        template = 'base.html'

class PostPage(Page):
    hero_title =  models.CharField(max_length=255)

Я хочу отобразить атрибуты post_1 и post_2 в body StreamField:

base.html:

{% for block in page.body %}
    {% include_block block %}
{% endfor %}

post-grid.html:

{{ value.post_1.url }}
{{ value.post_1.hero_title }}

value.post_1.url отображает URL нормально. Однако value.post_1.hero_title остается пустым.

Как отобразить атрибуты страницы?

Когда вы используете PageChooserBlock() без указания дополнительных опций, Wagtail не знает заранее, каким будет тип страницы при ее получении, и поэтому возвращает базовый экземпляр Page, который состоит только из основных полей, общих для всех типов страниц, таких как title.

В этом случае, предположительно, только страницы PostPage должны быть разрешены для этих переключателей, поэтому вы можете указать это в определении PageChooserBlock:

class PostGrid(blocks.StructBlock):
    title = blocks.CharBlock()
    post_1 = blocks.PageChooserBlock(page_type='myapp.PostPage')
    post_2 = blocks.PageChooserBlock(page_type='myapp.PostPage')
    # replace 'myapp' with your app name

При таком изменении выборщик позволит выбирать только страницы типа PostPage, а в шаблоне value.post_1 и value.post_2 будут возвращаться как полные экземпляры PostPage, что позволит вам использовать hero_title.

Альтернативно, если вы не можете сделать это изменение, потому что есть несколько разрешенных типов страниц, вы можете заставить его получить полный объект страницы с помощью .specific:

{% with value.post_1.specific as post_1 %}
    {{ post_1.url }}
    {{ post_1.hero_title }}
{% endwith %}

Однако, каждый вызов specific будет выполнять дополнительный запрос к базе данных.

Вернуться на верх