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

Django自定义Serializer Field失效:添加SerializerMethodField报错

问题:Django序列化器添加自定义字段len_name报错

我尝试在Django序列化器中添加自定义字段len_name(使用SerializerMethodField),但添加后出现错误,异常信息:'MovieSerializer' object has no attribute 'len_name'

此前代码运行正常,以下是我的代码:

Model代码

from django.db import models

class Movie(models.Model):
    title = models.CharField(max_length=255, unique=True)
    description = models.TextField()
    active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(default=None, null=True)

    def __str__(self):
        return self.title

Serializer代码

from rest_framework import serializers
from watchlist_app.models import Movie
from watchlist_app.api.validations import MovieValidations


class MovieSerializer(serializers.ModelSerializer):
    len_name = serializers.SerializerMethodField(method_name='len_name')

    class Meta:
        model = Movie
        fields = "__all__"
        read_only_fields = ['id', 'len_name', 'created_at']
        required_fields = ['title', 'description']

        @staticmethod
        def create(self, validated_data):
            return Movie.objects.create(**validated_data)

        @staticmethod
        def update(self, instance, validated_data):
            instance.title = validated_data.get('title', instance.title)
            instance.description = validated_data.get('description', instance.description)
            instance.active = validated_data.get('active', instance.active)
            instance.save()
            return instance

        @staticmethod
        def get_len_name(self, obj):
            return len(obj.title)

        validators = [MovieValidations.validate_title, MovieValidations.validate_description,
                      MovieValidations.validate_equals]

问题根源及修复方案

1. 核心错误点

  • 方法位置错误:你把create、update、get_len_name这些序列化器方法嵌套在了Meta类内部,而DRF要求这些方法必须定义在序列化器类的顶层(和Meta同级),Meta仅用于存放模型关联、字段配置等元数据。
  • 方法名称不匹配:你在SerializerMethodField中指定了method_name='len_name',但实际定义的方法是get_len_name,DRF找不到指定的len_name方法,因此报错。

2. 修复后的Serializer代码

from rest_framework import serializers
from watchlist_app.models import Movie
from watchlist_app.api.validations import MovieValidations


class MovieSerializer(serializers.ModelSerializer):
    # 方案一:不指定method_name,DRF默认查找get_<字段名>格式的方法
    len_name = serializers.SerializerMethodField()
    # 方案二:显式指定method_name,需与实际方法名一致:method_name='get_len_name'

    class Meta:
        model = Movie
        fields = "__all__"
        read_only_fields = ['id', 'len_name', 'created_at']
        required_fields = ['title', 'description']
        validators = [MovieValidations.validate_title, MovieValidations.validate_description,
                      MovieValidations.validate_equals]

    # 移出Meta类,放在序列化器顶层
    def create(self, validated_data):
        return Movie.objects.create(**validated_data)

    # 移出Meta类,放在序列化器顶层
    def update(self, instance, validated_data):
        instance.title = validated_data.get('title', instance.title)
        instance.description = validated_data.get('description', instance.description)
        instance.active = validated_data.get('active', instance.active)
        instance.save()
        return instance

    # 移出Meta类,放在序列化器顶层;无需@staticmethod,DRF会自动传入obj参数
    def get_len_name(self, obj):
        return len(obj.title)

额外说明

  • DRF的SerializerMethodField默认会自动匹配get_<字段名>格式的方法,通常不需要显式指定method_name。
  • 序列化器的自定义方法(如create、update、字段方法)不需要添加@staticmethod,DRF会自动传递序列化器实例和模型对象作为参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 20:48:22