You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 14:52:57