Как создать схему для фильтра множественного выбора? - PullRequest
0 голосов
/ 23 апреля 2019

В нашем API у нас есть конечная точка для списка местоположений. Мы разрешаем фильтрацию по типу местоположения и разрешаем несколько значений для этого фильтра. Например:

GET /location/?type=hotel&type=airport

Для фильтрации мы используем django-filter. Однако drf-yasg, похоже, неправильно генерирует схему для этого параметра.

Класс представления можно свести к следующему:

from rest_framework.generics import ListAPIView
from .models import Location
from .serializers import LocationListSerializer
from .filters import LocationFilterSet
from django_filters.rest_framework import DjangoFilterBackend

class LocationListView(ListAPIView):
    queryset = Location.objects.all()
    serializer_class = LocationListSerializer
    filter_backends = (
        DjangoFilterBackend,
    )
    filter_class = LocationFilterSet

и класс фильтра выглядит следующим образом:

from django_filters import rest_framework as filters
from .models import Location

class LocationFilterSet(filters.FilterSet):
    type = filters.MultipleChoiceFilter(choices=Location.TYPE_CHOICES)

    class Meta:
        model = Location
        fields = (
            'type',
        )

Это представление работает как задумано - следующие тесты проходят:

from django.test import TestCase
from django.urls import reverse
from rest_framework import status
from .models import Location

class TestLocationView(TestCase):
    def test_filter_by_multiple_types(self):
        Location.objects.create(type='airport')
        Location.objects.create(type='hotel')
        Location.objects.create(type='home')
        response = self.client.get('/location/?type=hotel&type=airport')
        self.assertEqual(len(response.data), 2)

Я ожидаю, что сгенерированный yaml для этого параметра будет выглядеть следующим образом:

parameters:
- name: type
  in: query
  description: ''
  required: false
  schema:
      type: array
      items:
          type: string
  explode: true

но вместо этого это выглядит так:

- name: type
  in: query
  description: ''
  required: false
  type: string

Это ограничение drf-yasg?

Невозможно использовать swagger_auto_schema query_serializer, поскольку он не позволяет переопределить схемы, сгенерированные бэкэндами фильтра.

Похоже, это происходит потому, что django_filters.rest_framework.backends.DjangoFilterBackend.get_coreschema_field выводит только два типа поля: число и строки. Я пошел дальше и переопределил этот метод, однако затем он выдает ошибки в drf_yasg.inspectors.query.CoreAPICompatInspector.coreapi_field_to_parameter, не принимает тип массива.

...