pythonwagtailwagtail-streamfield

Wagtail Convert StreamField to Dict


I'm trying to convert a streamfield in models.py to a dict on save so then I can get the data and do something with it.

from django.http import JsonResponse
import json

class ProductBlogPage(BlogDetailPage):
    product_details = StreamField([
        ('product_name_and_url', blocks.ProductNameAndUrlBlock()),
    ],
        null=True, 
        blank=True,
        use_json_field=True,
    )

 def save(self, *args, **kwargs):
    # Here I want to turn the product_details data into a dict
    print('self.product_details')

On print it shows a bunch of HTML code created by StreamField so I could do it the hacky way and turn it into a string, manuiplate it with .replace and then import it into json or JsonResponse but I want to learn the correct way to do this.

When I do try to load it with json or JsonResponse I get the error

the JSON object must be str, bytes or bytearray, not StreamValue

Solution

  • product_details.raw_data is an array of dictionaries (one element per block), the only HTML should be for formatted rich text. This is the value stored in the db.

    You can loop through the array and access all your key/value pairs from there. e.g.

    <ul>    
        {% for product in self.product_details.raw_data %}
            <li>{{ product.sku }} - {{ product.name }}</li>
        {% endfor %}
    </ul>
    

    or pass it into some JS for processing and rendering

    {{self.product_details.raw_data|json_script:"product_details"}}
    <script>someJS('product_details')</script>