Search code examples
getdjango-rest-frameworkput

django-rest-framework: independent GET and PUT in same URL but different generics view


I'm using django-rest-framework and I need to map in the URL file two generic views with the same url (iḿ already using URLs but not Routes):

I need to allow GET, PUT and DELETE verbs in just one url (like /api/places/222) and allow everyone to get every field with the related Entity Place but just allow to update (PUT) one field using the same url.

Place Entity:

- id (not required in PUT)
- name (required always)
- date (not required in PUT but required in POST)

URL

url(r'^api/places/(?P<pk>\d+)/?$', PlacesDetail.as_view(), name='places-detail'),

I tried to use RetrieveDestroyAPIView and UpdateAPIView, but I'm unable to use just one URL.


Solution

  • I suggest you to create a few serializers that satisfy your needs. Then override the get_serializer method of your view so that the view switches serializers according to an HTTP request method.

    This is a quick untested example:

    class PlacesDetail(RetrieveUpdateDestroyAPIView):
    
        def get_serializer_class(self):
            if self.request.method == 'POST':
                serializer_class = FirstSerializer
            elif self.request.method == 'PUT':
                serializer_class = SecondSerializer
    
            return serializer_class
        ...
    
    

    Look at the base class method's comment:

    def get_serializer_class(self):
        """
        Return the class to use for the serializer.
        Defaults to using `self.serializer_class`.
    
        You may want to override this if you need to provide different
        serializations depending on the incoming request.
    
        (Eg. admins get full serialization, others get basic serialization)
        """
        ...