How do I override viewsets.ModelViewSet in Django REST Framework?

Viewed 4799

So my model is simple as

class Face(models.Model):
    uid = models.CharField(max_length=510, primary_key=True)
    photo = models.ImageField(upload_to='face_photos')

serializer

class FaceSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Face
        fields = ['uid', 'photo']
        extra_kwargs = {'uid': {'required': True}, 'photo': {'required': True}}

and view should be something like

class FaceViewSet(viewsets.ModelViewSet):
    queryset = Face.objects.all()
    serializer_class = FaceSerializer
    permission_classes = [permissions.AllowAny]

And it works. However:

  1. I don't want list, update, delete options. Only POST and GET.
  2. I want to add my logic on post, so if uid exists then update, else create... as well other processing.
  3. I want custom response after the POST.

How do I achieve this all not loosing all the goodies that viewsets.ModelViewSet provides, like validations, auto generated HTML fields in Rest API web view, etc?

2 Answers

This worked for me:

class FaceViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
    """
    API endpoint for adding and processing new client (by uid) face
    """
    queryset = Face.objects.all()
    serializer_class = FaceSerializer
    permission_classes = [permissions.AllowAny]

    def create(self, request):
        if "uid" in request.POST:
            try:
                instance = Face.objects.get(pk=request.POST['uid'])
                serializer = FaceSerializer(
                    instance=instance,
                    data=request.data
                )
            except Face.DoesNotExist:
                serializer = FaceSerializer(data=request.data)
        else:
            serializer = FaceSerializer(data=request.data)

        serializer.is_valid(raise_exception=True)
        serializer.save()

        return Response(serializer.data)

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = FaceSerializer(instance=instance)
        return Response(serializer.data)

for number one you can use this:

http_method_names = ['get','post']

buth get method also cintains list method

Related