Create a gist now

Instantly share code, notes, and snippets.

PUT-as-create mixin class for Django REST framework.
class AllowPUTAsCreateMixin(object):
"""
The following mixin class may be used in order to support PUT-as-create
behavior for incoming requests.
"""
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
instance = self.get_object_or_none()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
if instance is None:
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
lookup_value = self.kwargs[lookup_url_kwarg]
extra_kwargs = {self.lookup_field: lookup_value}
serializer.save(**extra_kwargs)
return Response(serializer.data, status=status.HTTP_201_CREATED)
serializer.save()
return Response(serializer.data)
def partial_update(self, request, *args, **kwargs):
kwargs['partial'] = True
return self.update(request, *args, **kwargs)
def get_object_or_none(self):
try:
return self.get_object()
except Http404:
if self.request.method == 'PUT':
# For PUT-as-create operation, we need to ensure that we have
# relevant permissions, as if this was a POST request. This
# will either raise a PermissionDenied exception, or simply
# return None.
self.check_permissions(clone_request(self.request, 'POST'))
else:
# PATCH requests where the object does not exist should still
# return a 404 response.
raise
@cancan101

PATCH is also allowed to create. From http://tools.ietf.org/html/rfc5789:

If the Request-URI does not
point to an existing resource, the server MAY create a new resource,
depending on the patch document type (whether it can logically modify
a null resource) and permissions, etc.

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