DRF中如何通过自定义Token激活用户(设is_active为True)
我来帮你梳理下这个问题哈~首先你的序列化器写法有点问题,get_token方法并不是用来处理激活逻辑的地方,咱们先把这个理顺,再选合适的视图。
一、先修正你的序列化器
你的ActivateUserSerializer里的get_token方法用错场景啦,这个方法是用来序列化输出字段值的,不是处理业务逻辑的。咱们应该把验证手机号和token的逻辑放在序列化器的validate方法里,让它承担数据校验的职责,这样视图层只需要处理业务动作就行:
from rest_framework import serializers from .models import UserProfile class ActivateUserSerializer(serializers.Serializer): phonenumber = serializers.CharField(required=True) token = serializers.CharField(required=True) def validate(self, attrs): phonenumber = attrs.get('phonenumber') token = attrs.get('token') # 验证手机号对应的用户存在 try: user_profile = UserProfile.objects.get(phonenumber=phonenumber) except UserProfile.DoesNotExist: raise serializers.ValidationError("该手机号对应的用户不存在") # 验证token匹配 if user_profile.first_token != token: raise serializers.ValidationError("激活Token不正确") # 把用户对象存到attrs里,方便视图后续直接使用 attrs['user_profile'] = user_profile return attrs
这里我把序列化器改成了Serializer而非ModelSerializer,因为咱们不需要序列化UserProfile的字段,只是接收手机号和token两个参数,这样更轻量也更贴合需求。
二、选择合适的视图:用
APIView实现自定义动作 因为这个激活操作不属于标准的CRUD(创建/读取/更新/删除),而是一个自定义的业务动作,用APIView是最灵活且合适的选择。你只需要继承APIView,实现post方法即可:
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from .serializers import ActivateUserSerializer class ActivateUserView(APIView): def post(self, request): serializer = ActivateUserSerializer(data=request.data) if serializer.is_valid(): # 从验证后的参数里取出用户对象 user_profile = serializer.validated_data['user_profile'] # 更新激活状态并保存 user_profile.is_active = True user_profile.save() return Response({"message": "用户激活成功"}, status=status.HTTP_200_OK) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
最后在你的urls.py里配置这个视图的路由:
from django.urls import path from .views import ActivateUserView urlpatterns = [ # 其他路由... path('user/activate/', ActivateUserView.as_view(), name='user-activate'), ]
三、为什么不选其他视图?
- 如果你用
ModelViewSet,也可以通过@action装饰器添加自定义动作,但对于这个简单的激活操作来说,APIView已经足够,没必要引入ViewSet的复杂度。 UpdateAPIView需要通过主键(pk)定位用户,但咱们的场景是通过手机号+token来匹配,不符合它的使用逻辑,所以不适合。
额外小建议
- 可以给
first_token字段添加过期时间,避免token长期有效,提升账号安全性。 - 激活成功后,可以考虑给用户发送短信/邮件通知,优化用户体验。
内容的提问来源于stack exchange,提问作者taghiss
相关产品推荐
相关产品推荐

