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

将DRF Serializer改为ModelSerializer后单元测试出现AssertionError

DRF ModelSerializer替换Serializer后测试失败的修复方案

问题分析与修复步骤

错误1:PATCH路由/api/users/8/中密码未更新

原因:ModelSerializer默认的update方法不会处理密码哈希,直接赋值密码会导致明文存储,测试无法验证更新效果。
修复:重写update方法,单独处理密码字段:

def update(self, instance: User, validated_data: dict) -> User:
    password = validated_data.pop('password', None)
    if password:
        instance.set_password(password)
    return super().update(instance, validated_data)

错误2:创建用户时未传数据缺少password必填键

原因:原Serializer中password是必填字段,但ModelSerializer的fields未包含password,且未设置required=True,导致序列化器不校验密码必填性。
修复:

  1. 在Meta.fields中添加password;
  2. 在extra_kwargs中为password设置required=True,同时给full_name添加required=False以匹配原规则:
class Meta:
    model = User
    fields = [
        "id", "username", "email", "password", "full_name", "artistic_name"
    ]
    extra_kwargs = {
        "password": {"write_only": True, "required": True},
        "full_name": {"required": False}
    }

错误3:密码未被正确哈希

原因:更新密码时未调用set_password方法,直接赋值导致密码明文存储。
修复:与错误1的修复一致,在update方法中调用instance.set_password(password)处理密码哈希。

额外补充:保持UniqueValidator行为一致

原Serializer中username有自定义的重复提示消息,ModelSerializer默认生成的消息可能不同,需手动添加validator以匹配原行为:

username = serializers.CharField(
    validators=[
        UniqueValidator(
            queryset=User.objects.all(),
            message="A user with that username already exists.",
        )
    ],
)
email = serializers.EmailField(
    validators=[UniqueValidator(queryset=User.objects.all())],
)

完整修复后的ModelSerializer代码

from rest_framework import serializers
from rest_framework.validators import UniqueValidator
from .models import User


class UserSerializer(serializers.ModelSerializer):
    username = serializers.CharField(
        validators=[
            UniqueValidator(
                queryset=User.objects.all(),
                message="A user with that username already exists.",
            )
        ],
    )
    email = serializers.EmailField(
        validators=[UniqueValidator(queryset=User.objects.all())],
    )

    def create(self, validated_data):
        return User.objects.create_user(**validated_data)

    def update(self, instance: User, validated_data: dict) -> User:
        password = validated_data.pop('password', None)
        if password:
            instance.set_password(password)
        return super().update(instance, validated_data)

    class Meta:
        model = User
        fields = [
            "id", "username", "email", "password", "full_name", "artistic_name"
        ]
        extra_kwargs = {
            "password": {"write_only": True, "required": True},
            "full_name": {"required": False}
        }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 08:27:47