Пропустить Django Rest Throttling Counter

Как я могу предотвратить дросселирование запроса Django rest, когда запрос пользователя недействителен или серверу не удалось завершить процесс?

Например, мне нужны параметры от пользователя, но когда пользователь не дает параметры, Django rest throttling все равно засчитывает их.

Есть ли решение, как пропустить счетчик дросселирования, когда запрос не успешен?

Пример

class OncePerHourAnonThrottle(AnonRateThrottle):
    rate = "1/hour"


class Autoliker(APIView):
    throttle_classes = [OncePerHourAnonThrottle]

    def get(self, request):
        content = {"status": "get"}
        return Response(content)

    def post(self, request):
        post_url = request.POST.get("url", None)
        print(post_url)

        content = {"status": "post"}
        return Response(content)

    def throttled(self, request, wait):
        raise Throttled(
            detail={
                "message": "request limit exceeded",
                "availableIn": f"{wait} seconds",
                "throttleType": "type",
            }
        )

Вы можете создать декоратор, чтобы сделать это.


class OncePerHourAnonThrottle(AnonRateThrottle):
    rate = "1/hour"

    def allow_request(self, request, view):
        """
        This function is copy of SimpleRateThrottle.allow_request
        The only difference is, instead of executing self.throttle_success
        it directly returns True and doesn't mark this request as success yet.
        """
        if self.rate is None:
            return True

        self.key = self.get_cache_key(request, view)
        if self.key is None:
            return True

        self.history = self.cache.get(self.key, [])
        self.now = self.timer()

        # Drop any requests from the history which have now passed the
        # throttle duration
        while self.history and self.history[-1] <= self.now - self.duration:
            self.history.pop()
        if len(self.history) >= self.num_requests:
            return False
        return True

def rate_limiter(view_function):
    @wraps(view_function)
    def inner(view_obj, request, *args, **kwargs):
        throttle = OncePerHourAnonThrottle()
        allowed = throttle.allow_request(request, None)
        if not allowed:
            raise exceptions.Throttled(throttle.wait())
        try:
            response = view_function(view_obj, request, *args, **kwargs)
        except Exception as exc:
            response = view_obj.handle_exception(exc)
        if response.status_code == 200:
            # now if everything goes OK, count this request as success
            throttle.throttle_success()
        return response

    return inner

class Autoliker(APIView):
   
    @rate_limiter
    def post(requests):
        # view logic
        pass

Это основная идея, как это можно сделать, теперь вы можете сделать это общим декоратором или даже декоратором на основе класса.

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