Django Rest Framework新用户注册需管理员激活问题求助
解决DRF注册用户is_active不生效及未激活用户登录限制问题
一、修复is_active=False不生效的问题
你的代码核心问题有两个:
- RegisterSerializer的create方法缩进错误,被嵌套在了
Meta类内部,导致该方法完全不会被执行; User.objects.create_user会直接将用户数据保存到数据库,修改is_active字段后必须调用user.save()才能把更改同步到数据库。
修正后的serializer.py代码:
class RegisterSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('id','username','password') extra_kwargs = { 'password':{'write_only': True} } # 将create方法移到RegisterSerializer类下,而非Meta内部 def create(self, validated_data): user = User.objects.create_user(validated_data['username'], password=validated_data['password']) user.is_active = False user.save() # 必须调用save()完成字段更新 return user class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = '__all__' extra_kwargs = { 'password':{ 'write_only': True } }
二、阻止未激活用户登录
根据你使用的认证方式,选择对应的实现方案:
方案1:基于DRF自带Token认证
重写ObtainAuthToken视图,添加is_active状态检查:
# views.py from rest_framework.authtoken.views import ObtainAuthToken from rest_framework.response import Response from rest_framework import status class CustomAuthToken(ObtainAuthToken): def post(self, request, *args, **kwargs): serializer = self.serializer_class(data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) user = serializer.validated_data['user'] if not user.is_active: return Response({'error': '账户未激活,请联系管理员'}, status=status.HTTP_401_UNAUTHORIZED) # 生成或获取用户令牌 from rest_framework.authtoken.models import Token token, created = Token.objects.get_or_create(user=user) return Response({'token': token.key, 'user_id': user.pk, 'username': user.username})
然后在urls.py中替换默认认证路由:
from django.urls import path from .views import CustomAuthToken urlpatterns = [ # 其他路由... path('api-token-auth/', CustomAuthToken.as_view(), name='api_token_auth'), ]
方案2:基于JWT认证(以djangorestframework-simplejwt为例)
重写Token获取序列化器,添加is_active校验:
# serializer.py from rest_framework_simplejwt.serializers import TokenObtainPairSerializer from rest_framework import serializers class CustomTokenObtainPairSerializer(TokenObtainPairSerializer): def validate(self, attrs): data = super().validate(attrs) if not self.user.is_active: raise serializers.ValidationError("账户未激活,请联系管理员") return data
在settings.py中配置使用自定义序列化器:
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_simplejwt.authentication.JWTAuthentication', ), } SIMPLE_JWT = { 'TOKEN_OBTAIN_SERIALIZER': 'your_app.serializers.CustomTokenObtainPairSerializer', }
内容的提问来源于stack exchange,提问作者Axel Siebert
相关产品推荐
相关产品推荐

