Django Rest 框架表单

Django Rest Framework Form

我想做的事情:

Django Rest Framework 带有一个渲染器,用于从序列化器[1] 返回一个HTML 表单。在仔细阅读了文档和代码之后,我仍然无法弄清楚如何让它呈现空白表单。

我认为问题可能是:

我不知道如何实例化空白序列化程序。在 DRF 的文档中,他们说序列化程序与 django 的表单非常相似 API。当您需要模板中的空白表单时,您可以使用 MyForm() 实例化一个并将其传递给模板上下文。但是,当我尝试使用序列化程序时,.data 属性只是 {'detail': 'Not Found.'}

请帮忙

我觉得我一定遗漏了一些非常明显的东西,因为呈现空白表单似乎是 HTMLFormRenderer 的一个非常重要的用例。

一些源代码

class CustomViewSet(ModelViewSet):
    lookup_field = 'id'
    pagination_class = MyCustomPagination
    serializer_class = MyModelSerializer
    renderer_classes = (JSONRenderer, BrowsableAPIRenderer, HTMLFormRenderer)

    def create(self, request, *args, **kwargs):
        # return an html form for GET requests to /api/my_model/create/.form

我很确定我的 urlconf 连接正确,请求在正确的位置结束,因为当我 GET /api/my_model/<pk>/.form 时,我得到一个响应表单,其中预先输入了模型属性.我只是想要一种获取空白表格的方法...

序列化程序必须声明至少一个字段才能使用它。

要创建一个绝对空白的序列化程序,只需添加一个 returns None 的自定义 SerializerMethodField 或一个接受空值的隐藏字段:

class EmptySerialiser(serializers.Serializer):
    empty = serializers.SerializerMethodField()

    def get_empty(self):
        return None

class EmptySerialiser(serializers.Serializer):
    empty = serializers.HiddenField(default=None,allow_null=True)

I can't figure out how to instantiate a blank serializer.

DRF 允许您初始化一个没有数据且没有附加实例的序列化程序。所以在你的情况下,你的视图代码看起来像

serializer = self.get_serializer()

I feel like I must be missing something blindingly obvious because rendering a blank form seems like a pretty major use case for an HTMLFormRenderer.

从那时起,serializer 应该包含呈现表单所需的所有信息。如果您想坚持使用 Django REST 框架呈现的默认表单,您可以使用它们提供的 the HTMLFormRenderer

serializer = self.get_serializer()
renderer = HTMLFormRenderer()
form_html = renderer.render(serializer.data)

请务必注意,HTMLFormRenderer 不受标准弃用政策的约束。因此,如果您确实使用它,请确保在升级时密切关注所有发行说明,以确保不会意外损坏。

我在我的视图集上使用以下方法设法 return 一个表单的 html 片段:

class CustomViewSet(ModelViewSet):

    @list_route()
    def form(self, request, *args, **kwargs):
        serializer = self.get_serializer()
        renderer = HTMLFormRenderer()
        form_html = renderer.render(serializer.data, renderer_context={
            'template': 'rest_framework/api_form.html',
            'request': request
        })
        return HttpResponse(form_html)

我需要使用 vanilla django HttpResponse,而不是 rest 框架的 Response 对象,以防止 Response 对象尝试使用视图集的默认渲染器重新渲染 form_html。此外,需要 list_route 装饰器来让 rest_framework 的 DefaultRouter 添加 my_model/form/ 端点,这并不意味着视图必须 return 列表。