如何在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
相关产品推荐
相关产品推荐

