if there are more than one fields with relations to other models and depth>=1 is specified on the serializer Meta class, in the example generated for the corresponding url, all of the relation fields have the same object as their value, for example:
model:
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)
serializer:
class OrderSerializer(serializers.ModelSerializer):
class Meta:
model = Order
fields = '__all__'
depth = 1
the example in echema:
{
"user": {
"number": 0
},
"type": {
"number": 0
}
}
there are also this warning:
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.
but if depth is not used and the related fields are assigned with their serializers the schema is correct:
serializer:
class OrderSerializer(serializers.ModelSerializer):
user = UserSerializer()
type = OrderTypeSerializer()
class Meta:
model = Order
fields = '__all__'
the example in schema:
{
"user": {
"username": "string",
"title": "string"
},
"type": {
"number": 0
}
}
how can the correct example be generated when nesting is done by using depth?
djangorestframework==3.12.3
drf-spectacular==0.20.2
This is from the DRF documentation:
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.
The problem is that drf-spectacular has a hard time knowing how the nested fields should be represented beforehand, since there is no "explicit" serializer.
I believe when depth
is used, DRF simply passes nested data through a on-the-fly ModelSerializer
and then does json.dump
.
Your second OrderSerializer
is the preferred way. It gives you more guarantees for you data exposure, and as an added benefit is parse-able by spectacular.
TL;DR: depth
is not supported at the moment. If you think this should be supported, open a github issue.