Проверить, активна ли учетная запись пользователя в Django Rest Framework - PullRequest
0 голосов
/ 04 апреля 2019

Я пытаюсь осуществить активацию аккаунта по электронной почте. Моя User модель очень проста, наследуется от django.contrib.auth.models.AbstractUser, поэтому по умолчанию имеет поле is_active. После регистрации новый пользователь создается с параметром is_active=False, и я хочу обработать случай, когда пользователь пытается войти в систему и даже если учетные данные в порядке, не должны входить в систему, потому что учетная запись не активирована. Я использую Knox Token Authentication. Мой сериализатор:

from django.contrib.auth import authenticate
from rest_framework import serializers, exceptions


class LoginUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserModel
        fields = ('username', 'password')

    def validate(self, data):
        user = authenticate(**data)
        if user:
            if user.is_active:
                return user
            raise exceptions.AuthenticationFailed('Account is not activated')
        raise exceptions.AuthenticationFailed()

И просмотр:

from django.contrib.auth import login
from rest_framework.permissions import AllowAny
from rest_framework.authtoken.serializers import AuthTokenSerializer
from knox.views import LoginView
from .serializers import LoginUserSerializer


class LoginUserView(LoginView):
    serializer_class = LoginUserSerializer
    permission_classes = [AllowAny]

    def post(self, request, *args, **kwargs):
        serializer = AuthTokenSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        login(request, user)
        return super(LoginUserView, self).post(request)

И с этим кодом я наткнулся на проблему: когда я пытаюсь войти в систему с уже активированной учетной записью, все выглядит нормально, но когда я пытаюсь неактивировать одну, вместо Account is not activated, я получаю:

{
    "non_field_errors": [
        "Unable to log in with provided credentials."
    ]
}

Что, я думаю, происходит скорее из поля зрения, чем из сериализатора.

1 Ответ

0 голосов
/ 04 апреля 2019

Хорошо, благодаря предложению Шафикура Рахмана я смог заставить его работать. После того, как я попытался отладить его с помощью pdb и установить трассировку внутри LoginUserSerializer, но ничего не произошло, я понял, что в своих взглядах я указываю не на написанный мной сериализатор, а на AuthTokenSerializer. Даже после этого он все еще не работал из-за моего непонимания того, как работает django login() и DRF validate(). Ниже фиксированный код для справки:

вид:

class LoginUserView(LoginView):
    serializer_class = LoginUserSerializer
    permission_classes = [AllowAny]

    def post(self, request, *args, **kwargs):
        serializer = LoginUserSerializer(data=request.data)  # changed  to desired serializer
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        login(request, user)
        return super(LoginUserView, self).post(request)

и сериализатор:

class LoginUserSerializer(serializers.ModelSerializer):
    username = serializers.CharField()  # added missing fields for serializer
    password = serializers.CharField()

    class Meta:
        model = UserModel
        fields = ('username', 'password')

    def validate(self, data):
        user = authenticate(**data)
        if user:
            if user.is_active:
                data['user'] = user  # added user model to OrderedDict that serializer is validating
                return data  # and in sunny day scenario, return this dict, as everything is fine
            raise exceptions.AuthenticationFailed('Account is not activated')
        raise exceptions.AuthenticationFailed()

Дополнительно, чтобы иметь возможность authenticate() не быть активным пользователем, мне пришлось добавить

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.AllowAllUsersModelBackend'
]

в настройках проекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...