How to let GraphQL read Streamfield
See original GitHub issueAny ideas how can I solve this problem to let StreamField read on GraphQL?
Below are the code and error show. after i run localhost:8080/graphql
schema.py
import graphene
from graphene_django import DjangoObjectType
from pages.models import Page
class PageType(DjangoObjectType):
class Meta:
model = Page
# Query
class Query(graphene.ObjectType):
pages = graphene.List(PageType)
def resolve_pages(self, info, **kwargs):
return Page.objects.all()
models.py
from wagtail.wagtailadmin.edit_handlers import TabbedInterface, ObjectList, StreamFieldPanel
from wagtail.wagtailcore.models import Page as WagtailPage, Orderable
from django.http import JsonResponse
from wagtail.wagtailcore.fields import StreamField
from wagtail.wagtailcore import blocks
from wagtail.wagtailimages.blocks import ImageChooserBlock
from wagtail.wagtaildocs.blocks import DocumentChooserBlock
from wagtail.wagtailsnippets.blocks import SnippetChooserBlock
from wagtail.wagtailsnippets.edit_handlers import SnippetChooserPanel
from wagtail.wagtailembeds.blocks import EmbedBlock
from modelcluster.fields import ParentalKey
from django.db import models
class PageIndex:
# Parent page / subpage type rules
parent_page_types = []
subpage_types = []
def serve(self, request):
return JsonResponse({
'title': self.title,
'body': self.body,
})
class CarouselBlock(blocks.StreamBlock):
image = ImageChooserBlock()
caption = blocks.TextBlock(blank=True)
class Meta:
icon = 'image'
class Page(WagtailPage):
body = StreamField([
('title', blocks.TextBlock(icon="title")),
('paragraph', blocks.RichTextBlock(editor='tinymce')),
('url', blocks.URLBlock()),
('blockquote', blocks.BlockQuoteBlock()),
('document', DocumentChooserBlock()),
('image', ImageChooserBlock()),
('media', EmbedBlock()),
('snippet', SnippetChooserBlock(target_model='contents.Content')),
], blank=True, null=True)
content_panels = WagtailPage.content_panels + [
StreamFieldPanel('body'),
]
edit_handler = TabbedInterface([
ObjectList(content_panels, heading='Contents'),
ObjectList(WagtailPage.promote_panels, heading='Promote'),
ObjectList(WagtailPage.settings_panels, heading='Settings', classname="settings"),
])
def get_url_parts(self, *args, **kwargs):
super(Page, self).get_url_parts(*args, **kwargs)
# Snippet Model
class PageContentPlacement(Orderable, models.Model):
page = ParentalKey('pages.Page', related_name='content_placements')
content = models.ForeignKey('contents.Content', related_name='+')
class Meta:
verbose_name = "content placement"
verbose_name_plural = "content placements"
panels = [
SnippetChooserPanel('content'),
]
def __str__(self):
return self.page.title + " -> " + self.content.description
Issue Analytics
- State:
- Created 6 years ago
- Reactions:2
- Comments:12 (2 by maintainers)
Top Results From Across the Web
Supporting StreamFields, Snippets and Images in a Wagtail ...
This tutorial shows you how you can create a Wagtail GraphQL API that supports StreamFields, Snippets, and Images in Wagtail.
Read more >Developers - How to let GraphQL read Streamfield - - Bountysource
Any ideas how can I solve this problem to let StreamField read on GraphQL? Below are the code and error show. after i...
Read more >Streamfields — wagtail-graphql-api documentation
Each Wagtail project will have its own definition of stream field blocks. wagtail-graphql-api does a job of serialising them. However each of the...
Read more >Customizing the behavior of cached fields - Apollo GraphQL
A read function that specifies what happens when the field's cached value is read ... Let's say our graph's schema includes the following...
Read more >How Hasura GraphQL Engine works
The Hasura GraphQL Engine automatically generates a unified GraphQL schema from your ... A subscription stream field with where , and cursor arguments....
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I created an implementation that works! And I’m posting it here, so that nobody has to struggle with it the way I did.
I’m not sure how Pythonic this solution is though.
First: I wanted to have a Union type for the StreamField so that I can use Inline Fragments in the GraphQL query for each block. As there are potentially many kinds of StreamFields in a wagtail app with different kinds of blocks I wanted to have a function that generates the Union type the way I want to have it. So, I created
create_stream_field_type
it returns a tuple with the graphene schema type and a resolver function.By default it resolves each block as a
GenericStreamBlock
. This is its implementation:This is how you use it:
And this is how a query would look like:
Now, this is cool and all, but it actually doesn’t help in any way.
To use the power of inline fragments you need to define a custom type for each block. Let’s start with a
ParagraphBlock
.All
paragraph
blocks are now resolved as aParagraphBlock
.The query could look like this now:
My paragraph blocks are pretty simple. I have some more complex StructBlocks though and this is where this implementation comes in really handy.
Finally this gives me all the power to create a query like this:
I hope this helps people who also want to implement a powerful GraphQL solution for StreamFields with Graphene.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.