Skip to content

Instantly share code, notes, and snippets.

@maxbellec
Created March 30, 2023 13:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maxbellec/2e346f2f59890329d76a4c73bb58b734 to your computer and use it in GitHub Desktop.
Save maxbellec/2e346f2f59890329d76a4c73bb58b734 to your computer and use it in GitHub Desktop.
Add a Django Rest Framework mixin for a GenericViewSet to replace create with an update_or_create method
from django.core.exceptions import ObjectDoesNotExist
from rest_framework import status
from rest_framework.mixins import CreateModelMixin
from rest_framework.response import Response
class UpdateOrCreateModelMixin(CreateModelMixin):
"""
Update or create a model instance.
"""
def create(self, request, *args, **kwargs):
try:
instance = self.get_or_update_object(request)
serializer = self.get_serializer(instance, data=request.data)
response_status = status.HTTP_200_OK
except ObjectDoesNotExist:
serializer = self.get_serializer(data=request.data)
response_status = status.HTTP_201_CREATED
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=response_status, headers=headers)
# Usage example
class ResponseView(
mixins.ListModelMixin, UpdateOrCreateModelMixin, viewsets.GenericViewSet
):
serializer_class = ResponseSerializer
queryset = Response.objects.all()
def get_or_update_object(self, request):
return self.get_queryset().get(
participation_id=request.data.get("participation_id"),
question_id=request.data.get("question_id"),
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment