Django REST drf-嵌套字段的惊人错误检测

Django REST drf-spectacular wrong detection of nested fields

如果有多个字段与其他模型有关系,并且在序列化器 Meta 上指定深度>=1 class,在为相应的 url 生成的示例中,所有的关系字段具有与其值相同的对象,例如:

型号:

class User(models.Model):
    username = models.CharField(max_length=255)
    title = models.CharField(max_length=255)

class OrderType(models.Model):
    number = models.IntegerField()

class Order(models.Model):
    user = models.ForeignKey('User', on_delete=models.PROTECT)
    type = models.ForeignKey('OrderType', on_delete=models.PROTECT)

序列化器:

class OrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = '__all__'
        depth = 1

echema 中的示例:

{
  "user": {
      "number": 0
  },
  "type": {
      "number": 0
  }
}

还有这个警告:

NestedSerializer: Encountered 2 components with identical names "Nested" and different classes <class 'rest_framework.serializers.ModelSerializer.build_nested_field.<locals>.NestedSerializer'> and <class 'rest_framework.serializers.ModelSerializer.build_nested_field.<locals>.NestedSerializer'>. This will very likely result in an incorrect schema. Try renaming one.

但如果不使用深度并且相关字段分配有它们的序列化程序,则模式是正确的:

序列化器:

class OrderSerializer(serializers.ModelSerializer):
    user = UserSerializer()
    type = OrderTypeSerializer()

    class Meta:
        model = Order
        fields = '__all__'

架构中的示例:

{
  "user": {
    "username": "string",
    "title": "string"
  },
  "type": {
    "number": 0
  }
}

深度嵌套如何生成正确的例子?

djangorestframework==3.12.3 
drf-spectacular==0.20.2

这来自 DRF 文档:

The depth option should be set to an integer value that indicates the depth of relationships that should be traversed before reverting to a flat representation. If you want to customize the way the serialization is done you'll need to define the field yourself.

问题是 drf-spectacular 很难事先知道应该如何表示嵌套字段,因为没有“显式”序列化程序。

我相信当使用 depth 时,DRF 只是通过即时 ModelSerializer 传递嵌套数据,然后 json.dump.

您的第二个 OrderSerializer 是首选方式。它为您的数据公开提供了更多保证,并且作为一个额外的好处,可以通过 spectacular 进行解析。

TL;DR: 目前不支持 depth。如果您认为这应该得到支持,请打开一个 github 问题。