Swagger 布尔参数值 True/False 而不是 true/false 和 django_filters

问题描述 投票:0回答:2

Swagger UI 以“true/false”形式提交布尔参数,而 django 过滤器布尔字段需要 True/False(大写)。因此,当我通过 swagger 查询时,字段 is_published 不起作用。

{{api_url}}/api/v1/games/?limit=10&offset=0&is_published=true
{{api_url}}/api/v1/games/?limit=10&offset=0&is_published=false

过滤字段定义为

is_published = BooleanFilter(name='versions__is_published')

完整定义

class GameFilter(FilterSet):
    """Custom filter for ``GameViewSet``.

    Defines custom filter for ``genres`` field (based on TaggableManager).

    """

    is_published = BooleanFilter(name='versions__is_published')

    class Meta:
        model = Game

        fields = {
            'platforms':  ['exact'],
            'ages':       ['exact'],
            'developers': ['exact'],
            'genres':     ['exact'],
            'created':    ['gt', 'lt']
        }

方法的 Swagger 定义

get:
  summary: Get list of games
  operationId: getGamesList
  parameters:
    - $ref: '../../parameters.yaml#/Offset'
    - $ref: '../../parameters.yaml#/Limit'
    - $ref: '../../parameters.yaml#/PlatformsFilter'
    - $ref: '../../parameters.yaml#/DevelopersFilter'
    - $ref: '../../parameters.yaml#/GenresFilter'
    - $ref: '../../parameters.yaml#/AgesFilter'
    - $ref: '../../parameters.yaml#/SearchFilter'
    - $ref: '../../parameters.yaml#/Order'
    - name: is_published
      in: query
      type: boolean
      required: false
      default: true

enter image description here

django swagger swagger-ui django-filter django-filters
2个回答
2
投票

解决方案

基础 django_filters.FilterSet 旨在与普通 Django 视图一起使用。如果您使用 DRF 创建 API,则应该使用 django_filters.rest_framework.FilterSet,因为它使用一组略有不同的过滤器,更适合在 API 中使用。在这种情况下,BooleanFilter 接受小写 true/false 值。

调整导入后:

from django_filters import ModelMultipleChoiceFilter
from django_filters.rest_framework import BooleanFilter, FilterSet

0
投票

DRF 中 BooleanFilter 的问题在于它利用了模型过滤器 - 它依赖于类似 python 的值(True 或 False,大写 T。)

为了使其更加灵活,我通常创建自己的 BooleanFilter 版本,该版本更通用:

from django_filters.rest_framework import *
from django_filters.rest_framework import (BooleanFilter as OrigBooleanFilter)
class BooleanFilter(OrigBooleanFilter):
    def filter(self, qs, value):
        if value:
            if value.lower() in ('true', 't', 'y', 'yes', '1'):
                value = True
            else:
                value = False

        return super().filter(qs, value)

然后导入此模块而不是 django_filters.rest_framework,这可以让您为自己的副本定义其他过滤器(和增强功能)。

我通常还会创建特殊的过滤器类来:

  • 允许“__in”过滤器中存在空值
  • 添加对部分json数组字段过滤的支持
  • 其他各种特殊用例过滤器。
© www.soinside.com 2019 - 2024. All rights reserved.