marcgibbons / django-rest-swagger

Swagger Documentation Generator for Django REST Framework: deprecated
https://marcgibbons.com/django-rest-swagger/
BSD 2-Clause "Simplified" License
2.59k stars 602 forks source link

Issue with NestedSerializer: Serializer definition is shown for only one related model type #398

Open maltem-za opened 8 years ago

maltem-za commented 8 years ago

Model being serialized (simplified):

class Service(models.Model):
    categories = models.ManyToManyField(Category)
    keywords = models.CharField(max_length=500)
    organisation = models.ForeignKey(Organisation)

Serializer definition:

class ServiceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Service
        depth = 1

print repr(serializer):

ServiceSerializer():
    id = IntegerField(label='ID', read_only=True)
    keywords = CharField(max_length=500)
    verified_as = CharField(allow_blank=True, max_length=100, required=False)
    age_range_min = IntegerField(allow_null=True, max_value=32767, min_value=0, required=False)
    age_range_max = IntegerField(allow_null=True, max_value=32767, min_value=0, required=False)
    availability_hours = CharField(allow_blank=True, max_length=50, required=False)
    organisation = NestedSerializer(read_only=True):
        id = IntegerField(label='ID', read_only=True)
        name = CharField(max_length=100)
        about = CharField(allow_blank=True, max_length=500, required=False)
        address = CharField(allow_blank=True, max_length=500, required=False)
        telephone = CharField(allow_blank=True, max_length=50, required=False)
        email = EmailField(allow_blank=True, max_length=254, required=False)
        web = URLField(allow_blank=True, max_length=200, required=False)
        location = ModelField(allow_null=True, model_field=<django.contrib.gis.db.models.fields.PointField: location>, required=False)
        country = PrimaryKeyRelatedField(queryset=Country.objects.all())
        areas = PrimaryKeyRelatedField(allow_empty=False, many=True, queryset=CountryArea.objects.all())
    categories = NestedSerializer(many=True, read_only=True):
        id = IntegerField(label='ID', read_only=True)
        name = CharField(max_length=50)

As you can see there are 2 NestedSerializers here, one for the Organisation model and one for the Category model. The endpoint is an APIView that declares the response_serializer explicitly in the YAML docstring.

The problem (see attached screenshot) is that only one of the NestedSerializer definitions is shown. In this case the one for Category. I have also seen the one for Organisation show up, in which case the one for Category is missing.

drs_bug

slykar commented 7 years ago

It's because the OpenAPI Renderer is using CoreAPI Renderer to supply Swagger with schema. The problem is, CoreAPI does not support nested fields definition. I can not find any info about defining custom types either.

However, DRF already provides a full schema as metadata. http://www.django-rest-framework.org/api-guide/metadata/

It seem to also be used internally for the Browseable API. The way OpenAPI is generated should use metadata instead relying on the CoreAPI I guess.