用Django Rest Framewor快速写一个注册、登录、改密码的api

最近上IOS马甲包,做马甲包的时候需要用到一个用户登录、注册、改密码的那么一个功能,所以临时弄了一个。 假设你已经安装了Django和Django Rest Framework,并且已经配置好了一个名为users的应用。 1、首先,安装并设置drf的认证模块: 在项目的settings.py中添加以下内容:

   INSTALLED_APPS = [
       # ...
       'rest_framework',
       'rest_framework.authtoken',  # 自动为用户生成token
       'users',  # 你的用户应用
   ]

   REST_FRAMEWORK = {
       'DEFAULT_AUTHENTICATION_CLASSES': (
           'rest_framework.authentication.TokenAuthentication',  # 使用Token验证
           # 'rest_framework.authentication.SessionAuthentication',  # 如果需要session验证也可以添加
       ),
       'DEFAULT_PERMISSION_CLASSES': (
           'rest_framework.permissions.IsAuthenticated',  # 只允许已认证用户访问
       ),
   }

2、在users应用下创建序列化器 serializers.py:

   from django.contrib.auth import authenticate, get_user_model, password_validation
   from rest_framework import serializers

   User = get_user_model()

   class RegisterSerializer(serializers.ModelSerializer):
       password2 = serializers.CharField(style={'input_type': 'password'}, write_only=True)

       class Meta:
           model = User
           fields = ['username', 'email', 'password', 'password2']
           extra_kwargs = {'password': {'write_only': True}}

       def validate(self, attrs):
           if attrs['password'] != attrs['password2']:
               raise serializers.ValidationError({"password": "The two password fields didn't match."})
           password_validation.validate_password(attrs['password'], user=self.instance)
           return attrs

       def create(self, validated_data):
           return User.objects.create_user(**validated_data)

   class LoginSerializer(serializers.Serializer):
       username = serializers.CharField()
       password = serializers.CharField(style={'input_type': 'password'})

       def validate(self, data):
           user = authenticate(request=self.context.get('request'), username=data['username'], password=data['password'])
           if not user:
               raise serializers.ValidationError("Invalid credentials")
           self.context['user'] = user
           return data

   class ChangePasswordSerializer(serializers.ModelSerializer):
       old_password = serializers.CharField(style={'input_type': 'password'})
       new_password = serializers.CharField(style={'input_type': 'password'})
       new_password2 = serializers.CharField(style={'input_type': 'password'})

       class Meta:
           model = User
           fields = ['old_password', 'new_password', 'new_password2']
           extra_kwargs = {'old_password': {'write_only': True}, 'new_password': {'write_only': True}, 'new_password2': {'write_only': True}}

       def validate(self, attrs):
           if attrs['new_password'] != attrs['new_password2']:
               raise serializers.ValidationError({"new_password": "The two password fields didn't match."})
           user = self.context['request'].user
           if not user.check_password(attrs['old_password']):
               raise serializers.ValidationError({"old_password": "Old password is incorrect."})
           password_validation.validate_password(attrs['new_password'], user=user)
           return attrs

       def update(self, instance, validated_data):
           instance.set_password(validated_data['new_password'])
           instance.save()
           return instance

3、创建views.py处理HTTP请求:

   from rest_framework import generics
   from .serializers import RegisterSerializer, LoginSerializer, ChangePasswordSerializer

   class RegisterView(generics.CreateAPIView):
       serializer_class = RegisterSerializer

   class LoginView(generics.GenericAPIView):
       serializer_class = LoginSerializer

       def post(self, request, *args, **kwargs):
           serializer = self.get_serializer(data=request.data)
           serializer.is_valid(raise_exception=True)
           user = serializer.validated_data['user']
           token, created = Token.objects.get_or_create(user=user)
           return Response({'token': token.key})

   class ChangePasswordView(generics.UpdateAPIView):
       serializer_class = ChangePasswordSerializer

       def get_object(self):
           return self.request.user

4、最后,在urls.py中配置路由:

   from django.urls import path
   from .views import RegisterView, LoginView, ChangePasswordView

   urlpatterns = [
       path('register/', RegisterView.as_view(), name='register'),
       path('login/', LoginView.as_view(), name='login'),
       path('change-password/', ChangePasswordView.as_view(), name='change_password'),
   ]

以上代码实现了一个基本的用户注册、登录以及密码修改API。请注意,在实际项目中,可能还需要添加更多的错误处理、权限控制和数据校验逻辑。

评论 0