Как получить объект request в методе __init__ Django REST framework?

Как можно более эффективным и правильным образом обеспечить доступ к переменной `requests` из другого эндпоинта внутри метода `__init__` класса `FooBarAPI`? Возможно ли более элегантное решение для обработки get-параметров в методах `foo` и `bar`?
  • 20 июня 2024 г. 12:02
Ответы на вопрос 2
В Django REST framework объект `request` доступен внутри методов представлений, но не в методе `__init__` класса представления. Однако, можно передать `request` как аргумент при инициализации объекта класса представления.

Пример:

```python
from rest_framework.views import APIView
from rest_framework.response import Response

class FooBarAPI(APIView):
    def __init__(self, request, *args, **kwargs):
        self.request = request
        super().__init__(**kwargs)
    
    def get(self, request):
        params = request.query_params
        # обработка get-параметров
        return Response({'message': 'GET request processed'})
    
    def post(self, request):
        # обработка post-запроса
        return Response({'message': 'POST request processed'})
```

Для доступа к объекту `request` из другого эндпоинта внутри метода `__init__` класса `FooBarAPI` можно передать `request` как параметр при создании экземпляра класса. Например:

```python
class OtherAPI(APIView):
    def get(self, request):
        foo_bar_api = FooBarAPI(request)
        foo_bar_api.foo()
        foo_bar_api.bar()
        return Response({'message': 'Other GET request processed'})
```

Для более элегантного решения обработки get-параметров в методах `foo` и `bar` можно использовать декораторы `@action` и `@detail_route` из модуля `rest_framework.decorators`. Например:

```python
from rest_framework.decorators import action

class FooBarAPI(APIView):
    @action(detail=False, methods=['get'])
    def foo(self, request):
        params = request.query_params
        # обработка get-параметров для метода foo
        return Response({'message': 'GET request processed in foo'})

    @action(detail=False, methods=['get'])
    def bar(self, request):
        params = request.query_params
        # обработка get-параметров для метода bar
        return Response({'message': 'GET request processed in bar'})
```

Таким образом, можно более элегантно и компактно обрабатывать запросы и параметры для различных методов представления в Django REST framework.
В DRF объект request доступен лишь в методах, которые выполняются при обработке запроса. В init методе доступ к request получить невозможно, так как init выполняется при создании экземпляра класса, а не при обработке запроса. 

НО! Как вариант, можно создать метод, который будет выполняться перед запросом, например, использовать метод initial в классе ViewSet, например:

from rest_framework import viewsets, status
from rest_framework.response import Response


class FooBarAPI(viewsets.ViewSet):

    def initial(self, request, *args, **kwargs):
        # request доступен
        super().initial(request, *args, **kwargs)
        self.get_params(request)

    def get_params(self, request):
        self.query_params = request.query_params

    def foo(self, request, *args, **kwargs):
        print(self.query_params)
        return Response("foo", status=status.HTTP_200_OK)

    def bar(self, request, *args, **kwargs):
        print(self.query_params)
        return Response("bar", status=status.HTTP_200_OK)
Похожие вопросы