Wagtail:序列化页面模型

时间:2017-03-01 18:50:35

标签: python json django serialization wagtail

我使用wagtail作为网站的REST后端。该网站使用反应并通过Wagtails API v2获取数据。

SPA网站需要能够以不确定的方式显示页面的预览。我的想法是覆盖页面模型上的serve_preview并简单地将新页面作为JSON将其写入并将其写入可以由我的前端访问的缓存。但我无法将我的页面序列化为json。所有的尝试都感到非常“hackish”

我已经多次尝试使用串行器内置的扭曲扩展但没有成功:

尝试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)

在这里使用路由器并设置一堆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)

更好,但我得到了背景问题:

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'

有什么难事吗?

2 个答案:

答案 0 :(得分:2)

可能是一个非答案的答案,但我在DRF,Wagtail在DRF之上的分层以及缓存json结果的需求方面也遇到了挑战(DRF目前还没有内置缓存)正如我所知,这是一个额外的挑战)。在最近的一个项目中,我最终只是在一个视图中构建了一个字典列表,并将它们与app一起发回,完全绕过了DRF和Wagtail API。代码最终简单易读,易于缓存:

HttpResponse()

不如使用预先构建的REST框架那么优雅,但有时​​更简单的方法更有效...

答案 1 :(得分:1)

通过浏览源代码解决了这个问题。

首先定义一个空的虚拟视图:

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()

然后使用此视图并手动设置序列化程序的上下文。我也在我的上下文中使用与我的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})

别忘了导入:

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