Django Djoser自定义序列化器中validate_email方法无法调用问题排查
问题1:序列化器方法缩进错误
你写的validate_email方法缩进层级不对,不属于你自定义的UserCreateSerializer类,DRF的字段校验规则只会识别序列化器类内部定义的validate_<字段名>方法,所以不会触发调用。
问题2:查询方法拼写错误
ORM查询存在性的方法是exists(),你写的exist()少了末尾的s,就算方法被调用也会抛出异常。
问题3:序列化器类名冲突
你自定义的序列化器和继承的Djoser原生UserCreateSerializer同名,很容易出现导入错误,导致Djoser实际调用的还是原生序列化器,没有走你写的校验逻辑。
问题4:配置未生效排查点
如果改完上面的问题还不生效,确认你已经把accounts应用添加到了settings.py的INSTALLED_APPS列表中,否则Djoser找不到你定义的序列化器,会fallback到默认实现。
修复后的代码示例
1. 序列化器代码
# 先导入djoser的原生序列化器重命名避免冲突 from djoser.serializers import UserCreateSerializer as BaseUserCreateSerializer from rest_framework import serializers from .models import User # 自定义序列化器换个名字 class CustomUserCreateSerializer(BaseUserCreateSerializer): class Meta(BaseUserCreateSerializer.Meta): model = User fields = ("id","username","email","password") # 缩进和Meta类同级,属于自定义序列化器的方法 def validate_email(self, email): if User.objects.filter(email=email).exists(): msg = "email already taken" raise serializers.ValidationError(msg) return email
2. Djoser配置修改
DJOSER = { ..., "SERIALIZERS" : { # 替换成你修改后的序列化器路径 "user_create":"accounts.serializers.CustomUserCreateSerializer", "user":"accounts.serializers.CustomUserCreateSerializer", "user_delete":"djoser.serializers.UserDeleteSerializer", }, }
可选优化
如果要全局保证邮箱唯一性,可以直接在自定义User模型的email字段添加unique=True约束,DRF会自动生成对应的校验逻辑,不需要手动写validate_email方法:
from django.db import models from django.contrib import auth class User(auth.models.AbstractUser, auth.models.PermissionsMixin): # 新增email唯一约束 email = models.EmailField(unique=True) def __str__(self): return "@{}".format(self.username)
注意如果修改模型字段要执行makemigrations和migrate命令同步数据库结构。
内容的提问来源于stack exchange,提问作者Ahmed Yasin
相关产品推荐
相关产品推荐

