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

Django DRF调用SerializerMethodField的answer方法缺失2个必填位置参数

DRF SerializerMethodField 缺参数报错修复

报错信息

TypeError: answer() missing 2 required positional arguments: 'Poll' and 'Answers'

问题根因

serializers.SerializerMethodField绑定的回调方法参数签名不符合DRF框架的调用规则:

  • 序列化器中定义的实例方法,第一个固定参数必须是self
  • 框架调用该方法时,只会传入1个业务参数:当前正在被序列化的模型实例,也就是当前序列化器Meta.model指定的Poll类对应的数据行实例

原代码中answer方法除self之外额外声明了Options、Poll、Answers三个形参,框架调用时仅会传入当前Poll实例,剩余参数无对应传值,直接触发缺参报错。
除此之外原代码还存在几处写法问题:

  • 混淆类型注解和函数参数语法:类型注解的写法是参数名: 类型,不是把模型类直接写在参数列表里当形参
  • 重复查库:方法入参拿到的就是当前Poll实例,不需要再调用Poll.objects.get()重复查询当前对象
  • 循环内重复执行count查询,存在不必要的性能开销
  • 序列化器类名pollSerializer小写开头,不符合Python类名大驼峰命名规范

修正后代码

from rest_framework import serializers
from .models import Answers, Poll, Options
from authUser.models import User


class PollSerializer(serializers.ModelSerializer):
    class Meta:
        model = Poll
        fields = ["pollAnswer"]

    pollAnswer = serializers.SerializerMethodField(method_name="get_poll_answer")

    def get_poll_answer(self, obj: Poll):
        # obj为当前序列化的Poll实例,无需重复查库获取
        poll_type = obj.pollType
        if poll_type == 0:
            return obj.pollAnswer
        if poll_type == 1:
            options = Options.objects.filter(pollId=obj.pk)
            max_vote = 0
            target_option_id = 0
            for option in options:
                vote_count = Answers.objects.filter(pollId=obj.pk, optionId=option.pk).count()
                if vote_count > max_vote:
                    max_vote = vote_count
                    target_option_id = option.pk
            return target_option_id

写法规范提醒

  • 所有SerializerMethodField绑定的方法,固定签名为def 方法名(self, 当前序列化实例),需要用到其他模型直接在方法内部调用查询即可,不需要写在参数列表里
  • 类型注解仅做类型提示用,不会实际参与参数传递,不要把类型声明当成形参写
  • 序列化单条数据时直接使用框架传入的实例对象即可,避免重复查库

内容的提问来源于stack exchange,提问作者mehdi_ahmadi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 04:51:25