Как разрешить дросселирование только в том случае, если ответ был успешным?

Я пытаюсь сделать дросселирование на OTP аутентификации, чтобы пользователь мог отправлять только одно сообщение в минуту

class BurstRateThrottle(AnonRateThrottle, UserRateThrottle):
    scope = 'burst'
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES':
    ('rest_framework_simplejwt.authentication.JWTAuthentication',),
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ],
    'DEFAULT_THROTTLE_RATES': {
        'burst': '1/min',
        'anon': '200/min',
        'user': '250/min',
    },
@api_view(['POST'])
@permission_classes([AllowAny])
@throttle_classes([BurstRateThrottle])
def login_send_token(request):
    ...

Проблема в том, что api получает дросселирование, даже если номер телефона неправильный, поэтому я пытаюсь дросселировать только когда отправляется сообщение OTP или когда ответ 200 или 201

Есть ли способ получить доступ к коду статуса ответа в методе allow_request? или вручную выполнить дроссель из функции, которая вызывает twilio api?

Метод allow_request выполняется до метода, поэтому вы получаете результат запроса API только после того, как фреймворк решит, можно ли выполнить запрос или нет.

Одним из способов сделать это может быть выполнение запроса к API в методе allow_request и добавление запроса в историю запросов только в случае успешного выполнения запроса API.

Однако, это путает места, где вы ожидаете найти этот код, поэтому альтернативой может быть встраивание пользовательского дросселирования непосредственно в ваш метод login_send_token.

Я решил эту проблему, преобразовав login_send_token в представление на основе классов

class LoginSendToken(APIView):
    permission_classes = [AllowAny]
    throttle_classes = [BurstRateThrottle]

после этого я переопределил initial метод и закомментировал self.check_throttles(request) вызов

    def initial(self, request, *args, **kwargs):
        """
        Runs anything that needs to occur prior to calling the method handler.
        """
        self.format_kwarg = self.get_format_suffix(**kwargs)

        # Perform content negotiation and store the accepted info on the request
        neg = self.perform_content_negotiation(request)
        request.accepted_renderer, request.accepted_media_type = neg

        # Determine the API version, if versioning is in use.
        version, scheme = self.determine_version(request, *args, **kwargs)
        request.version, request.versioning_scheme = version, scheme

        # Ensure that the incoming request is permitted
        self.perform_authentication(request)
        self.check_permissions(request)
        # self.check_throttles(request)

и вызвал check_throttles из моего метода post после проверки сериализатора теперь он проверяет дросселирование только если сериализатор был валидным

Вернуться на верх