Skip to content

Declaratively Expressing Asymmetric Request/Response Serializers #2898

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

Closed
cancan101 opened this issue May 1, 2015 · 4 comments
Closed

Declaratively Expressing Asymmetric Request/Response Serializers #2898

cancan101 opened this issue May 1, 2015 · 4 comments

Comments

@cancan101
Copy link
Contributor

There are a number of times where I want the request serializer (ie used when sending data in a POST/PUT/PATCH) to be different from the serializer used in the response (GET and potentially responses to POST, etc).

For example, I create an object without nesting but when I GET the endpoint, related objects may be included in the response.

An example of this is GitHub's API for PRs, POSTing a PR has a minimal set of fields: https://developer.github.com/v3/pulls/#create-a-pull-request
but GETting that PR has far more fields: https://developer.github.com/v3/pulls/#get-a-single-pull-request

It would be great if DRF supported this type of functionality and did so in a declarative nature.

@cancan101
Copy link
Contributor Author

I created this mixin :

class AsymmetricSerializersMixin(object):
    def get_serializer_response(self, serializer):
        if not hasattr(self, 'get_serializer_class_response'):
            return serializer

        serializer_class = self.get_serializer_class_response()
        if serializer_class is None:
            return serializer

        kwargs = {'context': self.get_serializer_context()}
        return serializer_class(serializer.instance, **kwargs)

and then a new version of CreateModelMixin:

class AsymmetricCreateModelMixin(AsymmetricSerializersMixin, mixins.CreateModelMixin):
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        serializer = self.get_serializer_response(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

It will try to use get_serializer_class_response where it is defined.

@tomchristie
Copy link
Member

On balance I see this as possibly valid at some future point, but out of scope right now (let's keep focused on existing bugs, and the upcoming admin style interface)

@cancan101
Copy link
Contributor Author

Any reason not to keep the ticket open, but tag it with a "Someday" milestone?

@tomchristie
Copy link
Member

I think it's good for the health of the project if we treat the issue list as stuff that we feel is active and currently in scope. Note that there's probably plenty on the list right now that also needs pruning.

There's a non-finite amount of stuff that could go in "someday".

Here's my general take on managing large projects... http://www.dabapps.com/blog/sustainable-open-source-management/

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

No branches or pull requests

2 participants