从 wagtail 页面选择器获取图像和介绍文本

Get Image and intro text from wagtail page chooser

我在 wagtail admin 中加入了一个页面选择器,但是我想得到的是页面选择器的流块中每个项目的图像,并且想知道是否有办法做到这一点。所以假设如果我有一个类别索引页面,我将有以下代码:

{% if page.case_study %}
                            
   {% image page.case_study.image fill-50x50-c100 class="" %}
   {{ page.case_study }}
                           
{% endif %}    

我似乎得到的只是很好的链接,但我需要那个案例研究页面上的图片。我的模型如下:

class CategoryPage(Page):
"""
Detail view for a specific category
"""
introduction = RichTextField(
    help_text='Text to describe the page',
    blank=True)
image = models.ForeignKey(
    'wagtailimages.Image',
    null=True,
    blank=True,
    on_delete=models.SET_NULL,
    related_name='+',
    help_text='Landscape mode only; horizontal width between 1000px and 3000px.'
)
body = StreamField(
    BaseStreamBlock(), verbose_name="Page body", blank=True
)
case_study = StreamField([
    ('Cases', blocks.PageChooserBlock()),
], blank=True,
   null=True,
   verbose_name='Case Studies',
)
origin = models.ForeignKey(
    Country,
    on_delete=models.SET_NULL,
    null=True,
    blank=True,
)

category_type = models.ForeignKey(
    'categories.CategoryType',
    null=True,
    blank=True,
    on_delete=models.SET_NULL,
    related_name='+'
)

categories = ParentalManyToManyField('Category', blank=True)

content_panels = Page.content_panels + [
    FieldPanel('introduction', classname="full"),
    ImageChooserPanel('image'),
    StreamFieldPanel('body'),
    StreamFieldPanel('case_study'),
    FieldPanel('origin'),
    FieldPanel('category_type'),
]

search_fields = Page.search_fields + [
    index.SearchField('body'),
]

parent_page_types = ['CategoriesIndexPage']

如有任何帮助,我们将不胜感激

StreamField 是一个块列表,但是当您编写 page.case_study.image 时,您正试图访问它,就好像它只是一个项目一样。我建议您首先更新您的字段/块名称以使这种区别更清楚 - case_studies 是列表,其中的每个块都是一个 case(请注意,通常块名称较低 -案例):

case_studies = StreamField(
    [
         ('case', blocks.PageChooserBlock()),
    ],
    blank=True,
    null=True,
    verbose_name='Case Studies',
)

在您的模板中,您现在将遍历 page.case_studies。但是,这不会直接为您提供案例研究页面对象 - 列表中的每个项目都是一个 'block' 对象,具有 block_typevalue 属性。这是因为 StreamField 通常涉及混合多种块类型(而不仅仅是您在此处定义的一种类型),在这种情况下,您需要某种方法来找出您在循环的每次迭代中使用的块类型.

{% if page.case_studies %}
    {% for block in page.case_studies %}
         {# block.value now refers to the page object #}
    {% endfor %}
{% endif %}

下一个问题是您的 PageChooserBlock 目前允许您 select 任何页面类型。这意味着当你的模板被呈现时,它无法预先知道要检索哪种页面类型,所以(为了避免不必要的数据库查找)它 returns 它作为一个基本的 Page 实例它只包含所有页面共有的核心字段,例如 titleslug - 因此,您的 image 字段将无法通过 block.value.image 获得。您可以通过使用 block.value.specific.image 来解决这个问题,它执行额外的数据库查找以检索完整的页面数据 - 但是,更有效的方法是在 PageChooserBlock 上指定页面类型(假设您已经设置了专用页面输入您的案例研究):

    ('case', blocks.PageChooserBlock(page_type=CaseStudyPage)),

您的最终模板代码将变为:

{% if page.case_studies %}
    {% for block in page.case_studies %}
         {% image block.value.image fill-50x50-c100 class="" %}
    {% endfor %}
{% endif %}