Регулирование области видимости Django Rest Framework в представлении на основе функций

Хотел спросить, знает ли кто-нибудь способ или обходной путь, как установить разные области дросселя для разных методов запроса в функциональном представлении.

Например

@api_view(['GET', 'POST'])
def someFunction(request):
    if request.method == 'GET':
          # set scope for get requests
    elif request.method == 'POST':
          # set scope for post requests

Я пытался осмотреться, но все ответы предназначены только для представлений на основе классов. Буду признателен за помощь, спасибо.


person Omar Gaber El-Sayed    schedule 17.08.2020    source источник
comment
Доступно несколько вариантов. 1. декоратор 2. промежуточное ПО   -  person Talha Junaid    schedule 17.08.2020
comment
Не могли бы вы прислать мне ссылку или небольшой пример для промежуточного программного обеспечения или опций декоратора?   -  person Omar Gaber El-Sayed    schedule 17.08.2020
comment
Декоратор stackoverflow.com/a/49512224/3358570   -  person Talha Junaid    schedule 17.08.2020
comment
Поддержка Django rest framework запрашивает регулирование django-rest-framework.org/api-guide /дросселирование   -  person Talha Junaid    schedule 17.08.2020
comment
Для этого не существует стандартного метода. ИМХО, лучше портировать свои взгляды на мод CBV, чем повторно выполнять регулирование масштаба для вашего FBV.   -  person JPG    schedule 17.08.2020
comment
Я все равно хочу изменить их на CBV, но сейчас я хочу быстро исправить это. Я думал, что могу просто разделить представление API GET и POST на две функции и применить к ним регулирование области действия. Что вы думаете об этом подходе для быстрого исправления?   -  person Omar Gaber El-Sayed    schedule 17.08.2020


Ответы (2)


Вы можете решить эту проблему, сначала создав все пользовательские классы регулирования. Примечание. В классах находятся только дроссели, а представления — это функции.

class PostAnononymousRateThrottle(throttling.AnonRateThrottle):
    scope = 'post_anon'
    def allow_request(self, request, view):
        if request.method == "GET":
            return True
        return super().allow_request(request, view)

class GetAnononymousRateThrottle(throttling.AnonRateThrottle):
    scope = 'get_anon'
    def allow_request(self, request, view):
        if request.method == "POST":
            return True
        return super().allow_request(request, view)

class PostUserRateThrottle(throttling.UserRateThrottle):
    scope = 'post_user'
    def allow_request(self, request, view):
        if request.method == "GET":
            return True
        return super().allow_request(request, view)

class GetUserRateThrottle(throttling.UserRateThrottle):
    scope = 'get_user'
    def allow_request(self, request, view):
        if request.method == "POST":
            return True
        return super().allow_request(request, view)

Вы можете удалить классы, если вам не нужна аутентификация или тип метода.

Затем вам нужно импортировать это

from rest_framework.decorators import api_view, throttle_classes

Затем вы можете обернуть представление функции с помощью декоратора Throttle_classes со всеми созданными разрешениями.

@api_view(['GET', 'POST'])
@throttle_classes([PostAnononymousRateThrottle, GetAnononymousRateThrottle, PostUserRateThrottle, GetUserRateThrottle])
def someFunction(request):
    if request.method == 'POST':
        return Response({"message": "Got some data!", "data": request.data})
    elif request.method == 'GET':
        return Response({"message": "Hello, world!"})

Не забудьте указать скорость дросселя в settings.py.

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES': {
        'post_anon': '3/minute',
        'get_anon': '1/minute',
        'post_user': '2/minute',
        'get_user': '2/minute'
    }
}

Ссылка: https: //medium.com/analytics-vidhya/throttling-requests-with-django-rest-framework-for-other-http-methods-3ab0461044c

person Abhishek Bera    schedule 17.08.2020

Наконец-то я нашел обходной путь для представлений на основе функций. Вот как я это реализовал.

Как объяснялось в предыдущих ответах, нам нужно расширить класс UserRateThrottle или класс AnonRateThrottle в зависимости от наших потребностей.

В моем случае меня больше интересовало регулирование запросов от пользователей.

from rest_framework.throttling import UserRateThrottle

class CustomThrottle(UserRateThrottle):
     scope = 'my_custom_scope'
     def allow_request(self, request, view):
         if request.method == 'GET':
            self.scope = 'get_scope'
            self.rate = '2/hour'
            return True
         return super().allow_request(request, view)

И в настройках:

'DEFAULT_THROTTLE_RATES': {
        'my_custom_scope': '3/day'
}

По умолчанию этот класс будет регулировать запросы POST на основе скорости, установленной в файле настроек. Я добавил здесь изменение области действия и скорости в случае, если метод запроса был GET. Без этого изменения могут возникнуть некоторые проблемы из-за кэширования по умолчанию, используемого регуляторами DRF. Нам нужно установить скорость и область внутри самого класса CustomThrottle, иначе область, связанная с методом POST, будет применяться как к GET, так и к POST.

Наконец, мы добавляем декоратор в наше функциональное представление.

from rest_framework import api_view, throttle_classes
import CustomThrottle

@api_view(['GET', 'POST'])
@throttle_classes([CustomThrottle])
def someFunction(request):
    if request.method == 'GET':
          # set scope for get requests
    elif request.method == 'POST':
          # set scope for post requests

и все будет :D

person Omar Gaber El-Sayed    schedule 24.08.2020
comment
вы записали пользовательский дроссель в другой файл? - person indianLeo; 01.01.2021
comment
Да, это именно то, что я сделал. - person Omar Gaber El-Sayed; 02.01.2021