Правильный способ определения параметра списка в django-rest-framework и swagger

Фон

У меня есть следующее представление, и сопутствующий swagger UI генерируется django-spectacular:


class AllowedNameType(Enum):
    BRAND = "BRAND"
    ....

    @classmethod
    def list(cls):
        return list(map(lambda c: c.value, cls))

class GenerateCompanyNamesViewSet(viewsets.ViewSet):

    http_method_names = ["get"]
    
    def list(self, request: Request, *args, **kwargs) -> Response:
        """Generate suggested company names"""

        # query_params: dict = {}

        allowed_name_types: list[AllowedNameType] = query_params.get("allowed_name_types")
        suggestions: list[Suggestion] = ...

        return  Response(serializers.SuggestionSerializer(suggestions).data)

Я хочу добиться следующего:

  1. The swagger UI should have a parameter allowed_name_types which is a list of AllowedNameType values
  2. The input should be validated as per the serializer definition
  3. Type checking should be enforced on query_params to make sure the allowed_name_types is of type list[AllowedNameType] (ideally, allowed_name_types would actually be a named parameter in (eg list(..., allowed_name_types: list[AllowedNameType])

Попытка решения

class AllowedNameTypesParamSerializer(rest_framework_serializers.Serializer):

    allowed_name_types = rest_framework_serializers.ListField(
        child=rest_framework_serializers.ChoiceField(choices=models.AllowedNameType.list()),
        required=False,
        allow_empty=True,
    )

и добавил следующий декоратор к методу list:

@extend_schema(
        parameters=[
            OpenApiParameter(name="allowed_name_types", required=True, type=AllowedNameTypesParamSerializer),
        ],
        responses=serializers.FoodSearchAutoCompleteSerializer,
)
def list(....)

Это приводит к следующему интерфейсу: enter image description here

К сожалению:

  1. The swagger component expects a dictionary of {"allowed_name_types:...} instead of a list
  2. the allowed_name_types validation of list elements does not work (i.e I can put a value in the list that is not from AllowedNameType)
  3. Strangely, calling request.query_params.get('allowed_name_types') only returns the last value from the allowed_name_types.

Помощь?

Я уверен, что у меня есть все части лобзика для достижения того, что я хочу, но я не могу понять, как собрать их вместе, чтобы получить хорошо документированный API и типизированное проверенное поведение, которое мне нужно. Любая помощь будет очень признательна :)

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