'StreamChild' object is not iterable

1,191 views
Skip to first unread message

Olson Josué Dimanche

unread,
Feb 4, 2016, 7:56:44 PM2/4/16
to Wagtail support

 Hello guys, I am hoping that you can help me.
 Here is the template http://dpaste.com/2RZH7MS
 And here is the http://dpaste.com/3MTHRWF

 I am trying to seperate, or group them, in such the the surrounding text shows iff there is a value. Can you guys help me?
 I tried, slice, and it did not work, maybe I did it wrong. This one says that I can not iterate streamchild, and I can not find a way to break the loop in template.

 Thank you very much.

Matthew Westcott

unread,
Feb 5, 2016, 5:07:44 AM2/5/16
to wag...@googlegroups.com
Hi Olson,
Your code is failing because of the line {% if value in block %} - at this point 'block' refers to a single item in the stream, so it doesn't make sense to ask whether there's a value in it.

Django's template language isn't really a good fit for reorganising data like this. Changing your data model might be an option - I suspect that inline models <http://docs.wagtail.io/en/v1.3.1/topics/pages.html#inline-models> would be a better way of representing this data, although that would be quite a drastic change. (StreamField is designed for situations where you have different kinds of object mixed together in any order - e.g. synonym, category, antonym, category, category, definition... and if you find yourself wanting to "un-mix" them, that's a sign that StreamField is the wrong tool for this.) Alternatively, you could make use of ListBlock, so that each block in the stream is (for example) "a list of synonyms" rather than a single synonym:

body = StreamField([
...
('synonyms', blocks.ListBlock(SynonymBlock()))
])

If this isn't an option, I would suggest adding a get_context method to your page model - this allows you to perform extra processing before you start rendering the template. In this case, you'd use this to reorganise the StreamField content into separate sections:

class LemmaPage(Page):
...
def get_context(self, request):
context = super(LemmaPage, self).get_context(request)

context['synonym'] = [block.value for block in self.body if block.block_type == 'synonym']
# do the same thing for your other block types...

return context

Your list of synonyms will then be available in your template as the variable 'synonyms':

<article>
{% if synonyms %}
<h1>Synonyms</h1>
{% for value in synonym %}
{{ value }}
{% endfor %}
<hr/>
{% endif %}
</article>

Cheers,
- Matt
Reply all
Reply to author
Forward
0 new messages