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

如何在DRF中将默认用户认证改为自定义Tutor模型

实现自定义Tutor模型的Token认证

1. 修改Tutor模型适配认证系统

首先需要让你的Tutor模型兼容Django认证体系,继承AbstractBaseUser和PermissionsMixin,并实现必要的管理器类:

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager

class TutorManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError('邮箱字段不能为空')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('超级用户必须设置is_staff=True')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('超级用户必须设置is_superuser=True')

        return self.create_user(email, password, **extra_fields)

class Tutor(AbstractBaseUser, PermissionsMixin):
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    email = models.CharField(max_length=255, unique=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    objects = TutorManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    def __str__(self):
        return self.email

说明:

  • AbstractBaseUser提供密码哈希、认证核心方法(如set_password、check_password)
  • PermissionsMixin提供权限和超级用户管理功能
  • 自定义TutorManager确保用户创建时密码被正确哈希,以及超级用户的创建逻辑
  • USERNAME_FIELD指定用邮箱作为登录唯一标识
  • 移除原password字段,AbstractBaseUser已包含哈希后的密码存储字段

2. 配置settings.py指定默认用户模型

在项目settings.py中添加以下配置,替换your_app_name为Tutor模型所在的应用名称:

AUTH_USER_MODEL = 'your_app_name.Tutor'

注意:如果项目已有迁移记录,需清理数据库和应用下的迁移文件(保留__init__.py),再重新执行python manage.py makemigrations和python manage.py migrate,因为Django用户模型仅能在项目初始化时指定,后续修改需重置迁移。

3. 自定义Token获取视图

默认的obtain_auth_token视图基于默认User模型,需自定义视图适配Tutor:

from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
from django.contrib.auth import authenticate

class TutorAuthToken(ObtainAuthToken):
    def post(self, request, *args, **kwargs):
        email = request.data.get('email')
        password = request.data.get('password')
        user = authenticate(request, email=email, password=password)
        
        if user:
            token, created = Token.objects.get_or_create(user=user)
            return Response({
                'token': token.key,
                'user_id': user.pk,
                'email': user.email
            })
        return Response({'error': '无效的账号密码'}, status=400)

在urls.py中替换默认Token路由:

from django.urls import path
from .views import TutorAuthToken

urlpatterns = [
    path('api-token-auth/', TutorAuthToken.as_view(), name='api_token_auth'),
]

4. 实现注册视图

编写注册视图创建Tutor用户,确保密码被正确哈希:

from rest_framework import generics
from rest_framework.response import Response
from rest_framework.status import HTTP_201_CREATED
from .models import Tutor
from .serializers import TutorRegistrationSerializer

class TutorRegistrationView(generics.CreateAPIView):
    queryset = Tutor.objects.all()
    serializer_class = TutorRegistrationSerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()
        token, created = Token.objects.get_or_create(user=user)
        return Response({
            'user': serializer.data,
            'token': token.key
        }, status=HTTP_201_CREATED)

对应的序列化器TutorRegistrationSerializer:

from rest_framework import serializers
from .models import Tutor

class TutorRegistrationSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)

    class Meta:
        model = Tutor
        fields = ['first_name', 'last_name', 'email', 'password']

    def create(self, validated_data):
        password = validated_data.pop('password')
        user = Tutor.objects.create_user(**validated_data, password=password)
        return user

5. 测试认证流程

  • 发送POST请求到注册接口,创建Tutor用户,接口会返回生成的Token
  • 发送POST请求到api-token-auth/接口,传入邮箱和密码,获取Token
  • 后续接口请求在请求头中携带Authorization: Token <你的token>即可完成认证

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 14:36:19