Reputation: 17218
Imagine I have a Snippet
and a Page
containing it:
@register_snippet
class MySnippet(models.Model):
content = models.CharField(max_length=255)
class MyPage(Page):
snippet = models.ForeignKey('MySnippet', null=True, blank=True, on_delete=models.SET_NULL, related_name='+')
api_fields = [
APIFiled('snippet')
]
Now in the wagtail API page endpoint this page will look like this:
{
"id": 1,
"meta": { ... },
"snippet": {
"id": 1,
"meta": {
"type": "my_module.MySnippet"
}
}
}
What can I do to make this endpoint displaying snippet's content?
Also, how do I create a separate API endpoint only for snippets?
Upvotes: 4
Views: 2288
Reputation: 2645
An up to date APIViewSet (which older Wagtail versions would refer to as an APIEndpoint) would be:
class MyAPIViewSet(BaseAPIViewSet):
# BaseSerializer is enough for simple fields.
base_serializer_class = BaseSerializer
body_fields = BaseAPIViewSet.body_fields + ["field1", "field2"]
meta_fields = BaseAPIViewSet.meta_fields + ["field1"]
listing_default_fields = BaseAPIViewSet.listing_default_fields + ["field1", "field2"]
nested_default_fields = BaseAPIViewSet.nested_default_fields + ["field1"]
name = "mymodels"
model = MyModel
Then in api.py
:
api_router.register_endpoint("mymodels", MySnippetModelAPIEndpoint)
You have to create one such ViewSet for each Snippet you want to expose through the API.
Upvotes: 0
Reputation: 332
Here's how I did it, it was a simple enough representation though in my case
from rest_framework import serializers
class MyPage(Page):
snippet = models.ForeignKey('MySnippet', null=True, blank=True, on_delete=models.SET_NULL, related_name='+')
api_fields = [
APIField('snippet', serializer=serializers.StringRelatedField(many=True))
]
And you can add a 'str' method to your snippet
@register_snippet
class MySnippet(models.Model):
content = models.CharField(max_length=255)
def __str__(self):
return self.content
Upvotes: 5
Reputation: 421
I'm not sure how to answer the main question, but I can help with creating separate API endpoints for snippets.
You have to create an endpoints.py file in your app root, using the existing Wagtail endpoint classes as a base, such as BaseAPIEndpoint
Then, register the new endpoint in your api.py file.
endpoints.py
from wagtail.api.v2.endpoints import BaseAPIEndpoint
from .models import MySnippetModel
class MySnippetModelAPIEndpoint(BaseAPIEndpoint):
model = MySnippetModel
body_fields = BaseAPIEndpoint.body_fields + [
'field_1',
'field_2',
'field_3',
]
listing_default_fields = BaseAPIEndpoint.listing_default_fields = [
'field_1',
'field_2',
'field_3',
]
api.py
from .endpoints import MySnippetModelAPIEndpoint
...
sua_api_router.register_endpoint('snippets', MySnippetModelAPIEndpoint)
I would also look at the endpoints.py file in Wagtail core, so you can see what else you can extend or modify.
https://github.com/wagtail/wagtail/blob/master/wagtail/api/v2/endpoints.py
Upvotes: 6