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

如何扩展django-graphql-auth实现用户名、密码与邮箱校验?

问题原因

django-graphql-auth v0.3.16的默认注册突变逻辑并未直接调用自定义用户管理器的create_user方法,而是自行处理用户创建流程(比如直接实例化用户模型、设置密码后保存),导致你在管理器中定义的校验逻辑被跳过。

解决方法

方案1:重写注册突变,强制调用自定义管理器的create_user

通过自定义注册突变类,覆盖原逻辑,让用户创建流程强制走你定义的管理器校验:

  1. 在你的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
  1. 更新你的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 14:01:17