DRF单视图多序列化器时__init__报错:缺少instance参数
问题描述
在使用Django REST Framework(DRF)的generics.ListCreateAPIView编写MyListView视图时,根据self.role的值返回不同序列化器:
- 当
role为role1时返回Serializer1 - 当
role为role2时返回Serializer2 - 其他情况返回
Serializer3
同时为role2场景在get_serializer_context中添加了my_context参数。仅当self.role为role2时,出现错误:__init__() missing 1 required positional argument: 'instance'。该错误仅触发于使用自定义__init__方法的Serializer2,删除该方法后恢复正常。
相关代码如下:
class MyListView(generics.ListCreateAPIView): def get_serializer_class(self): if self.role == "role1": return Serializer1 elif self.role == "role2": return Serializer2 return Serializer3 def get_serializer_context(self): result = super().get_serializer_context() if self.role == "role2": result['my_context'] = something return result class Serializer2(ModelSerializer): ... def __init__(self, instance, **kwargs): super().__init__(instance, **kwargs) self.unit_id_list = self.context.get('my_context')
报错原因
问题出在Serializer2的自定义__init__方法参数定义上:
DRF序列化器在不同请求场景下的实例化逻辑不同:
- 执行**列表查询(List)**时,DRF会以无
instance参数的方式调用序列化器构造(实际是通过关键字参数传递,且instance默认值为None); - 执行创建(Create)或单实例查询/修改时,才会传入具体的
instance参数。
你定义的Serializer2.__init__把instance设为必填位置参数,没有设置默认值。当DRF在List场景下实例化Serializer2时,会以Serializer2(data=xxx, context=xxx)的方式调用,此时没有传位置参数的instance,就会触发缺失必填参数的错误。
正确的写法是让instance参数和DRF父类序列化器保持一致,设置默认值None:
class Serializer2(ModelSerializer): ... def __init__(self, instance=None, **kwargs): super().__init__(instance, **kwargs) self.unit_id_list = self.context.get('my_context')
这样无论DRF是在List(无instance)还是Create/Detail(有instance)场景下调用,都能正常实例化序列化器。
内容的提问来源于stack exchange,提问作者cappuccino wafer roll
相关产品推荐
相关产品推荐

