0

What am I trying to achieve will be easier to explain on lists. e.g

list_of_blocks=[1,2,3,4,5,6,7,8,9,10,11,12]
block_first_row = list_of_blocks[:3]
block_rest_rows = [list_of_blocks[i:i+4] for i in range(3, len(list_of_blocks), 4)]
block_rows = block_rest_rows.insert(0, list_of_blocks)

I want to group blocks from StreamField and display them in template grouped by those rows. Is there a way to do it in my model? Or should i do it somehow in template.. I've tried to do:

  • operate on StreamField as on list
  • deconstuct StreamField.. then operate as on list
Andreew4x4
  • 469
  • 4
  • 18

1 Answers1

2

The value of a StreamField is a list-like object of type StreamValue. Since it isn't a real list, it may not support slicing - if not, you can get around that by casting it to a real list with list(self.body) (where body is your StreamField). A good place to do this is the page's get_context method:

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

    list_of_blocks = list(self.body)
    block_first_row = list_of_blocks[:3]
    block_rest_rows = [list_of_blocks[i:i+4] for i in range(3, len(list_of_blocks), 4)]
    block_rows = block_rest_rows.insert(0, block_first_row)
    context['block_rows'] = block_rows

    return context

You can then access block_rows in your template:

{% for block_row in block_rows %}
    <div class="row">
        {% for block in block_row %}
            render block as normal, with {% include_block block %} or otherwise
        {% endfor %}
    </div>
{% endfor %}
gasman
  • 23,691
  • 1
  • 38
  • 56