继承DRF序列化器并将字段渲染为HiddenInput
问题描述
我正在复用第三方库中的Serializer,通过以下方式导入并定义序列化器以重写to_representation()方法:
class ExtendedSerializer(ThirdPartySerializer): def to_representation(self, value): return value
我的视图向序列化器填充数据并调用is_valid():
serializer = ExtendedSerializer( data={"key":"value"} ) serializer.is_valid()
模板通过如下方式渲染它:
{% render_form serializer template_pack='rest_framework/inline' %}
这种方式很好,让我无需创建大量表单来重复序列化器逻辑即可复用一小部分API。但我希望数据通过form.HiddenInput渲染(或通过某种通用方式将渲染的输入设置为type="hidden")。
如果是Django表单,我可以这样做:
class SomeForm(forms.Form): def __init__(self, *args, **kwargs): super(SomeForm, self).__init__(*args, **kwargs) self.fields['awesomefield'].widget = forms.MultipleHiddenInput()
我对DRF有些生疏——序列化器的类似实现方式是什么?
解决方案
1. 重写序列化器__init__方法修改字段Widget
和Django表单的思路一致,直接在序列化器的初始化方法中指定目标字段的Widget为隐藏类型:
from rest_framework import serializers from django.forms import HiddenInput class ExtendedSerializer(ThirdPartySerializer): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 为单个字段设置隐藏Widget self.fields['key'].widget = HiddenInput() # 若需要批量将所有字段设为隐藏,可循环处理 # for field_name in self.fields: # self.fields[field_name].widget = HiddenInput() def to_representation(self, value): return value
2. 自定义字段类默认使用隐藏Widget
如果需要重复使用隐藏字段的逻辑,可以自定义继承自DRF字段的类,默认绑定HiddenInput:
from rest_framework import serializers from django.forms import HiddenInput class HiddenCharField(serializers.CharField): def __init__(self, **kwargs): kwargs['widget'] = HiddenInput() super().__init__(**kwargs) # 在序列化器中替换原有字段 class ExtendedSerializer(ThirdPartySerializer): key = HiddenCharField() def to_representation(self, value): return value
注意:如果第三方序列化器的字段是动态生成的,此方法可能不适用,优先选择第一种方案。
3. 自定义渲染模板
若不想修改序列化器代码,可自定义DRF的表单渲染模板。复制DRF自带的inline模板文件,修改其中的输入渲染逻辑,将普通输入标签替换为<input type="hidden">即可。
内容的提问来源于stack exchange,提问作者user319862
相关产品推荐
相关产品推荐

