Сообщение пользовательского разрешения Django Rest Framework не отображается - PullRequest
0 голосов
/ 29 октября 2018

Я пишу приложение с Django Rest Framework.

Я создал собственное разрешение.Я предоставил атрибут message для пользовательского разрешения, но все равно возвращается деталь по умолчанию.

Позвольте мне дать вам мой код.

permissions.py:

from annoying.functions import get_object_or_None
from rest_framework import permissions

from intquestions.models import IntQuestion

from ..models import Candidate, CandidatePickedIntChoice

CANDIDATE_ALREADY_ANSWERED = "This candidate already answered all questions."


class CandidateAnsweredQuestionsPermission(permissions.BasePermission):
    """
    Permission to check if the candidate has answered all questions.
    Expects candidate's email or UUID in the request's body.
    """
    message = CANDIDATE_ALREADY_ANSWERED

    def has_permission(self, request, view):
        candidate = None
        email = request.data.get("email", None)
        if email:
            candidate = get_object_or_None(Candidate, email=email)
        else:
            uuid = request.data.get("candidate", None)
            if uuid:
                candidate = get_object_or_None(Candidate, uuid=uuid)

        if candidate:
            picked_choices = CandidatePickedIntChoice.objects.filter(
                candidate=candidate
            ).count()
            total_int_questions = IntQuestion.objects.count()

            if picked_choices >= total_int_questions:
                return False

        return True

views.py:

from annoying.functions import get_object_or_None
from rest_framework import generics, status
from rest_framework.response import Response

from ..models import Candidate, CandidatePickedIntChoice
from .permissions import CandidateAnsweredQuestionsPermission
from .serializers import CandidateSerializer


class CandidateCreateAPIView(generics.CreateAPIView):
    serializer_class = CandidateSerializer
    queryset = Candidate.objects.all()
    permission_classes = (CandidateAnsweredQuestionsPermission,)

    def create(self, request, *args, **kwargs):
        candidate = get_object_or_None(Candidate, email=request.data.get("email", None))
        if not candidate:
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
        else:
            serializer = self.get_serializer(candidate, data=request.data)
            serializer.is_valid(raise_exception=True)
            return Response(serializer.data, status=status.HTTP_200_OK)

Примечание: Приложение, которое я создаю, позволяет кандидатам отвечать на вопросы.Причина, по которой я переписал функцию создания следующим образом, заключается в том, что кандидаты, которые еще не завершили все вопросы, по-прежнему могут отвечать на все вопросы.

Почему сообщение о разрешении используется по умолчанию "Authentication credentials were not provided." вместо моегоесть?

1 Ответ

0 голосов
/ 29 октября 2018

В сообщении Authentication credentials were not provided. говорится, что вы не предоставили учетные данные .Он отличается от неверные учетные данные сообщение

Следующее, нет атрибута message для BasePermission class, поэтому он не будет использовать ваш атрибут message, если вы не принудительно.( Исходный код )

Как отобразить пользовательское сообщение PermissionDenied?
Исключение PermissionDenied повышено с permission_denied() Метод ove viewset, ( Исходный код )
Таким образом, ваше мнение должно быть как,

from rest_framework import exceptions


class CandidateCreateAPIView(generics.CreateAPIView):
    # your code
    def permission_denied(self, request, message=None):
        if request.authenticators and not request.successful_authenticator:
            raise exceptions.NotAuthenticated()
        raise exceptions.PermissionDenied(detail=CANDIDATE_ALREADY_ANSWERED)
...