Ric*_*ard 5 python django serialization json wagtail
我正在使用wagtail作为网站的REST后端。该网站是使用React构建的,并通过Wagtails API v2获取数据。
SPA网站必须能够显示w的页面预览。我的想法是serve_preview在页面模型上重写,然后简单地将新页面序列化为JSON并将其写入到可由前端访问的缓存中。但是我在将我的页面序列化为json时遇到麻烦。所有尝试都感觉很“骇人”
我已经尝试过使用序列化程序中内置的w的扩展名,但是没有成功:
豁免1:
def serve_preview(self, request, mode_name):
from wagtail.api.v2.endpoints import PagesAPIEndpoint
endpoint = PagesAPIEndpoint()
setattr(request, 'wagtailapi_router',
WagtailAPIRouter('wagtailapi_v2'))
endpoint.request = request
endpoint.action = None
endpoint.kwargs = {'slug': self.slug, 'pk': self.pk}
endpoint.lookup_field = 'pk'
serializer = endpoint.get_serializer(self)
Run Code Online (Sandbox Code Playgroud)
觉得在这里使用路由器并设置一堆attrs非常丑陋
尝试2:
def serve_preview(self, request, mode_name):
from wagtail.api.v2.endpoints import PagesAPIEndpoint
fields = PagesAPIEndpoint.get_available_fields(self)
if hasattr(self, 'api_fields'):
fields.extend(self.api_fields)
serializer_class = get_serializer_class(
type(self), fields, meta_fields=[PagesAPIEndpoint.meta_fields], base=PageSerializer)
serializer = serializer_class(self)
Run Code Online (Sandbox Code Playgroud)
更好,但我遇到了上下文问题:
Traceback (most recent call last):
...
File "/usr/local/lib/python3.5/site-packages/wagtail/api/v2/serializers.py", line 92, in to_representation
self.context['view'].seen_types[name] = page.specific_class
KeyError: 'view'
Run Code Online (Sandbox Code Playgroud)
有困难吗?
通过深入研究源代码解决了这个问题。
首先定义一个空的虚拟视图:
class DummyView(GenericViewSet):
def __init__(self, *args, **kwargs):
super(DummyView, self).__init__(*args, **kwargs)
# seen_types is a mapping of type name strings (format: "app_label.ModelName")
# to model classes. When an object is serialised in the API, its model
# is added to this mapping. This is used by the Admin API which appends a
# summary of the used types to the response.
self.seen_types = OrderedDict()
Run Code Online (Sandbox Code Playgroud)
然后使用此视图并手动设置序列化器的上下文。我也在我的上下文中使用与我的 api 相同的路由器。它具有由 PageSerializer 调用来解析某些字段的方法。有点奇怪,它与 wagtail api 如此紧密地耦合,但至少这是有效的:
def serve_preview(self, request, mode_name):
import starrepublic.api as StarApi
fields = StarApi.PagesAPIEndpoint.get_available_fields(self)
if hasattr(self, 'api_fields'):
fields.extend(self.api_fields)
serializer_class = get_serializer_class(
type(self), fields, meta_fields=[StarApi.PagesAPIEndpoint.meta_fields], base=PageSerializer)
serializer = serializer_class(
self, context={'request': request, 'view': DummyView(), 'router': StarApi.api_router})
Run Code Online (Sandbox Code Playgroud)
不要忘记导入:
from wagtail.api.v2.serializers import get_serializer_class
from rest_framework.viewsets import GenericViewSet
from rest_framework import status
from rest_framework.response import Response
from django.http import JsonResponse
from django.http import HttpResponse
Run Code Online (Sandbox Code Playgroud)