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

Wrapping serializer data in a response dict #463

Closed
aqeelat opened this issue Jul 22, 2021 · 6 comments
Closed

Wrapping serializer data in a response dict #463

aqeelat opened this issue Jul 22, 2021 · 6 comments

Comments

@aqeelat
Copy link

aqeelat commented Jul 22, 2021

Hi,

Most of our views return the following results in the following format:

Response(
    {"result": serializer.data, 'message': 'Loaded successfully', 'status': True},
    status=200
)

What's the best way to include that in the generated schema? I was able to do it via inline_serializer, but is there a way to do it en masse? Like, via a setting that says surround all returned serializers in another serializer.

@tfranzel
Copy link
Owner

Hi,

this is a special have we have dealt with before in issue #49

there is a relatively elegant workaround for these cases:

def enveloper(serializer_class, list):

for a global solution i would have to give it some more thought

@tfranzel
Copy link
Owner

closing this issue for now. feel free to comment if anything is missing or not working and we will follow-up.

@johnbridstrup
Copy link

I am also interested in a general solution to this. I have seen #49

@tfranzel
Copy link
Owner

This should get you pretty close. The enveloper helper is exactly the same. You just need to write a custom AutoSchema to apply this change to every response.

Remember to change DEFAULT_SCHEMA_CLASS to your CustomAutoSchema

from drf_spectacular.plumbing import get_class

def enveloper(serializer_class, many):
    component_name = 'Enveloped{}{}'.format(
        serializer_class.__name__.replace("Serializer", ""),
        "List" if many else "",
    )

    @extend_schema_serializer(many=False, component_name=component_name)
    class EnvelopeSerializer(serializers.Serializer):
        status = serializers.BooleanField()  # some arbitrary envelope field
        data = serializer_class(many=many)  # the enveloping part

    return EnvelopeSerializer

class CustomAutoSchema(AutoSchema):
    def get_response_serializers(self):
        """ use envelope on all default responses. @extend_schema will override this change """
        serializer_class = get_class(self._get_serializer())
        return enveloper(
            serializer_class=serializer_class,
            many=self._is_list_view(serializer_class)
        )

@johnbridstrup
Copy link

Thank you! Very helpful A+

@shalushaji
Copy link

shalushaji commented Apr 18, 2024

@tfranzel The enveloper works properly. But it is missing the paginated response. Outer fields are properly shown, but the paginated answer is missing. May be because of explicitly mentioned the serializer_class in the EnvelopeSerializer.

Respose i need

{
  "status": true,
  "detail": "Success",
  "code": 200,
  "data": {
    "count": 123,
    "next": "http://api.example.org/accounts/?offset=400&limit=100",
    "previous": "http://api.example.org/accounts/?offset=200&limit=100",
    "results": [
      {
        "id": "string",
        "code": "string",
        "address": "string",
        "latitude": 90,
        "longitude": 180,
        "created_on": "2024-04-18T06:40:27.086Z"
      }
    ]
  }
}

Response i getting

{
  "status": true,
  "detail": "Success",
  "code": 200,
  "data": [
    {
      "id": "string",
      "code": "string",
      "address": "string",
      "latitude": 90,
      "longitude": 180,
      "created_on": "2024-04-18T07:04:23.118Z"
    }
  ]
}

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

No branches or pull requests

4 participants