如何扩展django-graphql-auth实现用户名、密码与邮箱校验?
问题原因
django-graphql-auth v0.3.16的默认注册突变逻辑并未直接调用自定义用户管理器的create_user方法,而是自行处理用户创建流程(比如直接实例化用户模型、设置密码后保存),导致你在管理器中定义的校验逻辑被跳过。
解决方法
方案1:重写注册突变,强制调用自定义管理器的create_user
通过自定义注册突变类,覆盖原逻辑,让用户创建流程强制走你定义的管理器校验:
- 在你的app下创建
mutations.py:
from graphql_auth.mutations import RegisterMixin import graphene from django.core.exceptions import ValidationError from .models import CustomUser class CustomRegisterMutation(RegisterMixin, graphene.Mutation): class Arguments: email = graphene.String(required=True) username = graphene.String(required=True) password1 = graphene.String(required=True) password2 = graphene.String(required=True) @classmethod def perform_create(cls, root, info, **kwargs): # 校验密码一致性(保留原注册逻辑的基础校验) if kwargs["password1"] != kwargs["password2"]: raise cls.ValidationError({"password2": ["Passwords do not match."]}) # 调用自定义管理器的create_user,触发你的校验逻辑 try: user = CustomUser.objects.create_user( email=kwargs["email"], username=kwargs["username"], password=kwargs["password1"] ) except ValidationError as e: # 将Django验证错误转换为GraphQL可识别的格式返回 raise cls.ValidationError(e.message_dict) return user
- 更新你的
schema.py,替换默认的注册突变:
import graphene from graphql_auth.schema import UserQuery, MeQuery from .mutations import CustomRegisterMutation class Query(UserQuery, MeQuery, graphene.ObjectType): pass class Mutation(graphene.ObjectType): register = CustomRegisterMutation.Field() # 保留其他需要的graphql-auth突变(比如verify_account、login等) schema = graphene.Schema(query=Query, mutation=Mutation)
方案2:在自定义用户模型的clean方法中添加校验
如果不想重写突变逻辑,可以将校验逻辑迁移到用户模型的clean方法中——Django模型在保存前调用full_clean时会自动触发该方法,无论创建流程是通过管理器还是直接实例化:
from django.db import models from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin from django.core.exceptions import ValidationError from django.core.validators import validate_email class CustomUserManager(BaseUserManager): def create_user(self, email, username, password=None, **extra_fields): email = self.normalize_email(email) user = self.model(email=email, username=username, **extra_fields) user.set_password(password) user.save(using=self._db) return user class CustomUser(AbstractBaseUser, PermissionsMixin): email = models.EmailField(unique=True) username = models.CharField(max_length=150, unique=True) is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) objects = CustomUserManager() USERNAME_FIELD = "email" REQUIRED_FIELDS = ["username"] def clean(self): super().clean() # 邮箱格式校验 try: validate_email(self.email) except ValidationError: raise ValidationError({"email": "Invalid email format"}) # 用户名长度校验 if len(self.username) < 3: raise ValidationError({"username": "Username must be at least 3 characters long"}) # 其他自定义校验逻辑...
额外检查
确保settings.py中已正确配置自定义用户模型:
AUTH_USER_MODEL = "your_app_name.CustomUser"
内容的提问来源于stack exchange,提问作者Homunculus Reticulli
相关产品推荐
相关产品推荐

