0

如果有多个字段与其他模型有关系,并且在序列化程序 Meta 类上指定了 depth>=1,则在为相应 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
4

1 回答 1

0

这是来自 DRF 文档:

depth 选项应设置为一个整数值,该值指示在恢复为平面表示之前应遍历的关系深度。如果您想自定义序列化的完成方式,您需要自己定义字段。

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

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

你的第二种OrderSerializer是首选方式。它为您的数据暴露提供了更多保证,并且额外的好处是可以通过壮观的解析。

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

于 2021-11-24T12:21:01.513 回答