0

I have created a custom photoBlock to embed photos in a blog post. I am trying to create a template tag that would allow me to get every photoBlock that is stored in the database, almost like you query pages in Wagtail. I would prefer not to have to create a separate page for every photo, but instead be able to display them on a different page if possible via the template tag.

class photoBlock(blocks.StructBlock):
     date = blocks.DateBlock("Date Image Was Taken")
     location = blocks.CharBlock(max_length=100)
     image = ImageChooserBlock()
     latitude = blocks.DecimalBlock(max_digits=9, decimal_places=6)
     longitude = blocks.DecimalBlock(max_digits=9, decimal_places=6)
     description = blocks.RichTextBlock()

I am able to get the following to work, but it feels like the query is very heavy and will get bogged down once I have a bunch of posts.

for page in BlogPage.objects.all():
     for block in page.body.stream_data:
          if block['type'] == 'photoBlock':
               return block

Is there any better way to query a specific block from Streamfield? Anytime I try something like this

photoBlock.objects.all()

I always get an error response that photoBlock doesn't have attribute Object. Any ideas?

2 Answers2

1

Unfortunately there's no more efficient way to query StreamField blocks than looping over all the pages that contain them, as you're doing in your code snippet. This is a limitation of StreamField's implementation - the data is stored as a string of JSON on the page object, rather than the blocks being "true" database objects.

gasman
  • 23,691
  • 1
  • 38
  • 56
  • hey thanks for the quick reply. Would you have any suggestions on how to better possibly structure my models then? One idea I have is to create a page model for each photo and then embed it via a PageChooserBlock or something. – Austin Grandt Jun 08 '17 at 17:45
0

No real answer here either. What you could do to improve your query is to check if the string 'photoBlock' is present in the page body. The stream data is simply stored as a JSON string so that would yield only pages which contain that block.

Johan
  • 390
  • 4
  • 11