I am incorporating a page chooser in wagtail admin, however what I want to get is the image for each item in the streamblock for the page chooser and was wanting to know if there is a way to do this. So lets say if I have a category index page I would have the following code:
{% if page.case_study %}
{% image page.case_study.image fill-50x50-c100 class="" %}
{{ page.case_study }}
{% endif %}
All I seem to get are the links which is fine, but I need the image from that case study page. My model is as follows:
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']
Any help would be greatly appreciated
A StreamField is a list of blocks, but when you write
page.case_study.image
you're trying to access it as if it's only a single item. I'd suggest you start by updating your field / block names to make this distinction clearer -case_studies
is the list, and each block in it is a singlecase
(note that conventionally block names are lower-case):In your template, you will now loop over
page.case_studies
. However, this will not give you the case study page objects directly - each item in the list is a 'block' object, withblock_type
andvalue
properties. This is because a StreamField usually involves mixing multiple block types (rather than just the one type you've defined here) and in that situation, you need some way of finding out what block type you're working with on each iteration of the loop.The next issue is that your
PageChooserBlock
currently lets you select any page type. This means that when your template is rendered, it has no way to know up-front which page type to retrieve, so (in order to avoid unnecessary database lookups) it returns it as a basicPage
instance which only contains the core fields that are common to all pages, such astitle
andslug
- consequently, yourimage
field will not be available throughblock.value.image
. You can get around this by usingblock.value.specific.image
which performs the extra database lookup to retrieve the complete page data - however, a more efficient approach is to specify the page type on the PageChooserBlock (assuming you've set up a dedicated page type for your case studies):Your final template code then becomes: