将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,导致序列化器不校验密码必填性。
修复:
- 在
Meta.fields中添加password; - 在
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
相关产品推荐
相关产品推荐

