Skip to content

Instantly share code, notes, and snippets.

@venkatesh22
Forked from ahankinson/generics.py
Created May 8, 2014 09:14
Show Gist options
  • Save venkatesh22/9c092e2c30bae17ba29e to your computer and use it in GitHub Desktop.
Save venkatesh22/9c092e2c30bae17ba29e to your computer and use it in GitHub Desktop.
from rest_framework import mixins
from rest_framework.generics import SingleObjectAPIView
from yourapp.mixins import PartialUpdateModelMixin
class RetrievePartialUpdateDestroyAPIView(PartialUpdateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
SingleObjectAPIView):
@property
def allowed_methods(self):
"""
Return the list of allowed HTTP methods, uppercased.
"""
self.http_method_names.append("patch")
return [method.upper() for method in self.http_method_names
if hasattr(self, method)]
def get_serializer(self, instance=None, data=None, files=None, partial=False):
"""
Return the serializer instance that should be used for validating and
deserializing input, and for serializing output.
"""
serializer_class = self.get_serializer_class()
context = self.get_serializer_context()
return serializer_class(instance, data=data, files=files, partial=partial, context=context)
def patch(self, request, *args, **kwargs):
return self.update_partial(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
from django.http import Http404
from rest_framework import status
from rest_framework.response import Response
class PartialUpdateModelMixin(object):
"""
Update a model instance.
Should be mixed in with `SingleObjectBaseView`.
"""
def update_partial(self, request, *args, **kwargs):
try:
self.object = self.get_object()
created = False
except Http404:
self.object = None
created = True
serializer = self.get_serializer(self.object, data=request.DATA, files=request.FILES, partial=True)
if serializer.is_valid():
self.pre_save(serializer.object)
self.object = serializer.save()
status_code = created and status.HTTP_201_CREATED or status.HTTP_200_OK
return Response(serializer.data, status=status_code)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# A Sample View to demonstrate how to use the PATCH method
from yourapp.generics import RetrievePartialUpdateDestroyAPIView
from yourapp.models import Project
from yourapp.serializers import ProjectSerializer
class ProjectDetail(RetrievePartialUpdateDestroyAPIView):
model = Project
permission_classes = (permissions.AllowAny,)
serializer_class = ProjectSerializer
# your serializer class should not need to change.
Some curl commands to help test:
Create:
curl -XPOST -H "Content-type: application/json" -d '{"project_name":"My Project", "project_description":"The original description"}' http://localhost:8000/projects/
Update:
curl -XPATCH -H "Content-type: application/json" -d '{"project_name":"A new name"}' http://localhost:8000/project/1/
OR
curl -XPUT -H "Content-type:application/json" -d '{"project_name":"A new name", "project_description":"The original description"}' http://localhost:8000/project/1/
Delete:
curl -XDELETE http://localhost:8000/project/1/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment