Как я могу добавить бэкэнды фильтров в представление на основе функций? - PullRequest
0 голосов
/ 24 января 2019

Мне нужно выставить определенный метод в моем приложении Django. Этот метод не включает какие-либо модели или сериализаторы и является просто вычислительным. Поэтому я решил, что это было бы хорошим местом для использования Представлений на основе функций . Я также хочу, чтобы это представление отображалось в чванстве. Это так, но нет места для пользователя, чтобы подключить данные (см. Снимок экрана): enter image description here

Если бы я использовал GenericAPIView, я мог бы установить filter_backends, но я даже не знаю, возможно ли это с помощью базовых представлений функций.

Любая помощь приветствуется. Спасибо!

Обновление: вот метод, который я раскрываю:

@api_view(['POST'])
def host_pre_mm_check(request):

        ... do a bunch of computation ...

        response_dict = {
            "cluster_name": cluster_name,
            "failed": failed_host_names,
            "passed": passed_host_names
        }
        return Response(response_dict, status=status.HTTP_200_OK)

Вышеуказанный метод ожидает получения данных json, которые выглядят следующим образом:

{
   "cluster_name" : "A-VIF012",
   "host_names" : [
      "avif012-03.example.com",
      "avif012-05.example.com",
      "avif012-06.example.com",
   ]
}

Обновление 2: я пытался воспользоваться прекрасным советом Тоби, и я все еще получаю тот же результат в чванстве. Вот модификация, которую я сделал на основе предложений Тоби:

В моем view.py я добавил следующие строки:

from rest_framework.decorators import api_view, schema
from rest_framework.schemas import AutoSchema
from .serializers import *

class CustomAutoSchema(AutoSchema):
    pass

@api_view(['POST'])
@schema(CustomAutoSchema())
def cluster_host_pre_mm_check(request):

    ... lots of computational code ...

        response_dict = {
            "cluster_name": cluster_name,
            "failed": failed_host_names,
            "passed": passed_host_names
        }
        serializer = ClusterHostPreMMCheck(data=response_dict)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data
        return Response(data, status=status.HTTP_200_OK)

cluster_host_pre_mm_check.get_serializer = lambda *args: ClusterHostPreMMCheck

В моем serializers.py я добавил этот код:

class StringListField(serializers.ListField):
    child = serializers.CharField()


class ClusterHostPreMMCheck(serializers.Serializer):
    cluster_name = serializers.CharField(max_length=100)
    passed = StringListField()
    failed = StringListField()

Но в моем пользовательском интерфейсе нет места для ввода пользователем какого-либо ввода.

Обновление 3:

Подумав о том, что Тоби предложил по поводу определения сериализатора, я решил отказаться от использования базовых представлений функций и определил GenericAPIView. Затем я определил два класса сериализатора. Один для входных данных и один для выходных данных. Я установил serializer_class для входного сериализатора, который я определил, и я использовал выходной сериализатор в моем методе post(), когда я сериализирую ответ.

1 Ответ

0 голосов
/ 24 января 2019

Вы можете использовать rest framework декоратор shema вида для достижения этого

Чтобы переопределить генерацию схемы по умолчанию для представлений на основе функций, вы можете использовать декоратор @schema.Это должно следовать после (ниже) декоратора @api_view.Например:

from rest_framework.decorators import api_view, schema
from rest_framework.schemas import AutoSchema
from rest_framework.serializers import Serializer

class MySerializer(Serializer):
    a = serializers.CharField(max_length=100)
    b = serializers.CharField(max_length=100)


class CustomAutoSchema(AutoSchema):
    pass

@api_view(['GET'])
@schema(CustomAutoSchema())
def my_view(request):

    <.. do computation>
    result = {'a': 'ad', 'unwanted': None}

    # Validate payload before returning
    serializer = MySerializer(data=result)
    serializer.is_valid(raise_exception=True)
    data = serializer.validated_data  # {'a': 'ad'}

    return Response(data)

my_view.get_serializer = lambda *args: MySerializer

Примечание: filter_backends только для параметров фильтра, а не для определений схемы

Обновление:

ПросмотрИсходный код get_link создает ссылку на API ядра, используемую на интерактивной странице.

В вашем случае я предлагаю вам использовать логику get_serializer_fields

, поэтому после определения my_view

добавить строку типа

my_view.get_serializer = lambda *args: MySerializer

, где вы определили MySerializer со всеми вашими полями

...