Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Object support in response #1

Closed
MissiaL opened this issue Mar 6, 2020 · 3 comments
Closed

Object support in response #1

MissiaL opened this issue Mar 6, 2020 · 3 comments
Labels
enhancement New feature or request

Comments

@MissiaL
Copy link
Contributor

MissiaL commented Mar 6, 2020

Hi

Thanks for this cool project.

I have a problem with the response scheme
I would like to see the support of the object in the answer. I will show the code, I hope you will understand what I want to see

from unittest import mock

import uuid
from django.contrib.auth.models import AbstractUser
from django.db import models
from rest_framework import routers, serializers, viewsets

from drf_spectacular.openapi import AutoSchema, SchemaGenerator
from drf_spectacular.renderers import NoAliasOpenAPIRenderer


class Album(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=100)
    genre = models.CharField(
        choices=(('POP', 'Pop'), ('ROCK', 'Rock')),
        max_length=10
    )
    year = models.IntegerField()
    released = models.BooleanField()


class Song(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    album = models.ForeignKey(Album, on_delete=models.CASCADE)

    title = models.CharField(max_length=100)
    length = models.IntegerField()


class User(AbstractUser):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)


class AuthorSerializer(serializers.ModelSerializer):
    name = models.CharField(max_length=100)

    class Meta:
        model = User
        fields = (
            'id',
            'name',
        )


class SongSerializer(serializers.ModelSerializer):
    top10 = serializers.SerializerMethodField()
    author = serializers.SerializerMethodField()

    class Meta:
        fields = ['id', 'title', 'length', 'top10', 'author']
        model = Song

    def get_top10(self) -> bool:
        return True

    def get_author(self, obj):
        return AuthorSerializer(obj.user).data


class AlbumSerializer(serializers.ModelSerializer):
    songs = SongSerializer(many=True, read_only=True)

    class Meta:
        fields = '__all__'
        model = Album


class AlbumModelViewset(viewsets.ModelViewSet):
    serializer_class = AlbumSerializer
    queryset = Album.objects.none()

    def create(self, request, *args, **kwargs):
        """
        Special documentation about creating albums

        There is even more info here
        """
        return super().create(request, *args, **kwargs)


@mock.patch('rest_framework.settings.api_settings.DEFAULT_SCHEMA_CLASS', AutoSchema)
def test_basics():
    router = routers.SimpleRouter()
    router.register('albums', AlbumModelViewset, basename="album")
    generator = SchemaGenerator(patterns=router.urls)
    schema = generator.get_schema(request=None, public=True)
    schema_yml = NoAliasOpenAPIRenderer().render(schema, renderer_context={})

    with open('test_basic.yml') as fh:
        assert schema_yml.decode() == fh.read()

When I generate the schema, then author filed is string, but should be Author object
Like this
image

Is there any way to solve this problem?

@tfranzel
Copy link
Owner

tfranzel commented Mar 6, 2020

Hi @MissiaL
thank you so much! I know exactly what you mean, because we had that feature already on the list.

Regarging your example: The generator can't really know whats going on inside the method body unless you tell it. In easy cases you could use type hinting like with the -> bool. For serializers, you can't really do that with the type hinting mechanism (def x() -> AuthorSerializer:) or mypy would cry.

I will introduce a decorator for giving out non trivial types likes Serializer outputs. good catch!

@tfranzel tfranzel added the enhancement New feature or request label Mar 6, 2020
tfranzel added a commit that referenced this issue Mar 6, 2020
@extend_schema_field accepts Serializers and OpenApiTypes
@tfranzel
Copy link
Owner

tfranzel commented Mar 6, 2020

let me know if that works for you.

@MissiaL
Copy link
Contributor Author

MissiaL commented Mar 10, 2020

It works well. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants