登录和注册用户drf - Django Rest Framework框架,万能模版

     阅读:36

注册接口的实现

首先你需要定义好自己的注册序列化器

apps/user/serializer.py


class UserSignupSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    confirm_password = serializers.CharField(write_only=True)
    code = serializers.CharField(write_only=True)
    username = serializers.CharField()

    class Meta:
        model = User
        fields = [
            'id',
            'nickname',
            'username',
            'password',
            'confirm_password',
            'sex',
            'code'
        ]

    default_error_messages = {
        'code_error': '验证码不正确',
        'password_error': '两次密码输入不正确',
        "username_error": '手机号码格式不正确',
    }

    def validate(self, attrs):
        if not re.match(r'^1[3-9]\d{9}$', attrs['username']):
            raise ParamsException(self.error_messages['username_error'], 422)
        if attrs.get('code') != '123':
            raise ParamsException(self.error_messages['code_error'], 422)
        if attrs.get('password') != attrs.get('confirm_password'):
            raise ParamsException(self.error_messages['password_error'], 422)
        del attrs['confirm_password']
        del attrs['code']
        attrs['password'] = make_password(attrs['password'])
        return attrs

因为注册需要将信息写入到User表中,所以该序列化器继承自 serializers.ModelSerializer

此序列化器主要是对注册字段的校验,所以重写了validate方法

主要校验的字段为 username password confirm_password code(短信验证码),所以将他们定义到了序列化器中并对其在validate方法中进行了校验

ParamsException异常为自定义异常 utils/exception.py, 同时自定义了drf异常捕获

定义好之后需要加在settings.py:REST_FRAMEWORK中

REST_FRAMEWORK = {
    # 异常返回格式控制
    'EXCEPTION_HANDLER': 'utils.exception.custom_exception_handler',
}

apps/user/views.py

class UserSignupAPIView(CreateAPIView):
    serializer_class = UserSignupSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        user = serializer.instance

        Token.objects.get_or_create(user=user)
        data = {"code": 200, "msg": "成功"}

        return Response(
            data=data,
            status=status.HTTP_201_CREATED
        )

注册api继承了generics的CreateAPIView,在这里你可以重写post方法来定制你自己的api, 注册成功将Token记录到表中

Token表:from rest_framework.authtoken.models import Token

登录接口的实现

apps/user/serializer.py

class UserSigninSerializer(serializers.Serializer):
    username = serializers.CharField(required=True)
    password = serializers.CharField(required=True)

    default_error_messages = {
        'inactive_account': '用户已被禁用',
        'invalid_credentials': '账号或密码无效'
    }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.user = None

    def validate(self, attrs):
        self.user = authenticate(username=attrs.get("username"), password=attrs.get('password'))
        if self.user:
            if not self.user.is_active:
                raise ParamsException(self.error_messages['inactive_account'], 404)
            return attrs
        else:
            raise ParamsException(self.error_messages['invalid_credentials'], 404)

因为登录主要校验username和password的真实性,所以此序列化器继承自serializers.Serializer,重写__init__方法加入user,使其序列化成功后可携带user信息

重写validate方法完成username和password的校验

apps/user/views.py

class UserSigninAPIView(GenericAPIView):
    authentication_classes = ()
    permission_classes = ()
    serializer_class = UserSigninSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.user

        token, _ = Token.objects.get_or_create(user=user)
        data = {"code": 200, "msg": "成功", "data": {"token": token.key, "nickname": user.nickname}}

        return Response(
            data=data,
            status=status.HTTP_200_OK
        )

api接口继承自GenericAPIView基础类,并重写post方法完成登录的校验

来我的GitHub来看更多关于DRF的资料吧

十分钟学会DRF的企业级用法

https://github.com/Tengxu666/DRF_Professional