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连接正确,请求最终在正确的位置,因为当我获得/api/my_model/<pk>/.form
时,我得到一个表单作为响应,并预先输入了模型属性。我想要一种方法来获得一个空白的表格......
答案 0 :(得分:1)
我无法弄清楚如何实例化空白序列化器。
DRF允许您初始化没有数据且没有附加实例的序列化程序。因此,在您的情况下,您的视图代码看起来就像
serializer = self.get_serializer()
我觉得我必须错过一些令人眼花缭乱的东西,因为呈现一个空白表单似乎是HTMLFormRenderer的一个非常重要的用例。
从那时起,serializer
应该包含呈现表单所需的所有信息。如果你想坚持使用Django REST框架呈现的默认表单,你可以使用他们提供的the HTMLFormRenderer
。
serializer = self.get_serializer()
renderer = HTMLFormRenderer()
form_html = renderer.render(serializer.data)
请务必注意 HTMLFormRenderer
不受标准弃用政策的约束。因此,如果您确实使用它,请确保在升级时密切关注任何发行说明,以确保事情不会意外中断。
答案 1 :(得分:1)
我设法在我的视图集上使用以下方法返回表单的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对象尝试使用viewset的默认渲染器重新渲染form_html。另外,需要list_route装饰器来使rest_framework的DefaultRouter添加my_model/form/
端点,这并不意味着视图必须返回一个列表。
答案 2 :(得分:0)
序列化程序必须至少声明一个字段才能使用它。
要创建绝对空白的序列化程序,只需添加一个返回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)