【问题标题】:drf-spectacular issue with filterset_fieldsfilterset_fields 的 drf-spectacular 问题
【发布时间】:2021-04-16 11:27:02
【问题描述】:

我正在尝试将drf-spectacular 实现到现有的 Django REST API。

但是我在尝试运行时遇到以下错误

./manage.py spectacular --file schema.yml

错误:

python3.7/site-packages/django_filters/filterset.py", line 352, in get_filters
    "%s" % ', '.join(undefined)
TypeError: 'Meta.fields' contains fields that are not defined on this FilterSet: client, tenant_id, subtenant_id, data_stream_id

过滤器确实有效,但似乎与 drf-spectacular lib 配合得不好。谁能告诉我如何解决这个问题?

规格如下:

Python                3.7.2
Django                3.0.2    
django-filter         2.2.0    
django-rest-framework 0.1.0    
djangorestframework   3.12.1   
drf-spectacular       0.12.0 

视图集示例:

class subModelViewSet(viewsets.ModelViewSet):
    """Standard ViewSet for the DataStream Model."""
    queryset = DataStream.objects.all()
    serializer_class = DataStreamSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ('client', 'tenant_id', 'subtenant_id', 'data_stream_id',)

序列化器示例:

class DataStreamSerializer(serializers.ModelSerializer):
    """Class to validate an uploaded DataStream."""

    class Meta:
        """Nested Meta Class."""

        model = DataStream
        fields = '__all__'

【问题讨论】:

  • 有趣的问题。我有数百个视图,但没有一个有这个特殊问题。该错误看起来像是来自生成的 FilterSet(当您定义 filterset_fields 时),并不特别引人注目。能不能正常运行项目,如果能看到/docs/页面?
  • 嗨@AndrewBacker,事实上问题出在声明的filter_set字段上。特定的字段名称不是直接的模型之一,而是使用 ForeignKey 从父模型中引用的。一旦我从该视图集中删除了 filter_set,它就可以完美运行。将相应地更新问题。
  • 酷。我有很多 other 问题,但没有崩溃。您是否尝试为此视图创建自定义过滤器集?它应该为您提供更大的灵活性,同时还允许您过滤那些外键链接的字段
  • 0.12.0 以来,drf-spectacular(包括django-filter)有了很大的改进。 @Rogan88 请查看更新的版本。如果还有问题,请随时打开 github 问题。

标签: django django-rest-framework swagger django-filter drf-yasg


【解决方案1】:

原来是一个 Viewset 试图在 subModel 上应用 filterset_fields,它不直接包含这些字段,而是由另一个父模型上的 ForeignKey 引用。虽然我认为这些过滤器按预期工作,但我认为在这种情况下,对这些字段的实际过滤是由中间件执行的。

从视图集中删除字段可以毫无问题地生成架构。我能够访问完全呈现的 /docs 页面和 /schema 端点工作。到目前为止,drf-spectacular 给我留下了深刻的印象。

示例模型:

class DataSteam(models.Model):
    """Class for DataSteam Model."""
    client = models.CharField(max_length=200)
    tenant_id = models.CharField(max_length=200)
    subtenant_id = models.CharField(max_length=200)
    data_stream_id = models.CharField(max_length=200)

class subModel(models.Parent):
    """Class for storing linked datastream records."""
    ds = models.ForeignKey(DataStream, on_delete=models.CASCADE) 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 2022-07-29
    • 2021-08-11
    • 2021-10-26
    • 2022-11-03
    相关资源
    最近更新 更多