Django update ViewSet

djangoangular picture djangoangular · May 4, 2016 · Viewed 14.6k times · Source

Currently I am developing a image gallery django project. The user can upload images, and later upload a 'result' to each of the images. I know that I have to override the update(...) function, but I think I need help here with the Base64ImageFiled.

Step by step:

  1. User uploads image (result = null)
  2. Image gets stored in cloud
  3. User uploads result to a specified image (need help here)

Here is my current structure:

class Image(models.Model):
  project = models.ForeignKey(Project)
  image = models.ImageField(upload_to='images')
  result = models.ImageField(upload_to='results')

class ImageSerializer(serializers.ModelSerializer):
  project = ProjectSerializer(read_only=True, required=False)
  image = Base64ImageField(max_length=None, use_url=False)
  result = Base64ImageField(max_length=None, use_url=False, required=False)

class ProjectImagesViewSet(viewsets.ViewSet):
  queryset = Image.objects.select_related('project').all()
  serializer_class = ImageSerializer

  def list(self, request, project_pk=None):
    queryset = self.queryset.filter( project__name = project_pk)
    serializer = self.serializer_class(queryset, many=True)
    return Response(serializer.data)

  def update(self, request, pk=None, project_pk=None):
    print(request.data['result'])
    ???

Answer

mdargacz picture mdargacz · May 5, 2016

Django Rest Framework convention is to use partial_update instead of update (PATCH request method). If you will send PATCH request with image to the same url as for retrieve url is should get updated. if you require additional features on update then you can define:

class ProjectImagesViewSet(viewsets.ViewSet):
    #.....
    def partial_update(self, request, *args, **kwargs):
            instance = self.get_object()
            serializer = self.serialize(instance, data=request.data, partial=True)
            serializer.is_valid(raise_exception=True)
            #.... Your code ....
            serializer.save()
            return Response(serializer.data)

EDIT: Try those changes:

class ImageSerializer(serializers.ModelSerializer):
    project = ProjectSerializer(read_only=True, required=False)
    image = Base64ImageField(max_length=None, use_url=False)
    result = Base64ImageField(max_length=None, use_url=False, required=False)

    class Meta:
        model = Image


class ProjectImagesViewSet(viewsets.ViewSet):
    queryset = Image.objects.select_related('project').all()
    serializer_class = ImageSerializer

    def list(self, request, project_pk=None):
        queryset = self.queryset.filter(project__name=project_pk)
        serializer = self.serializer_class(queryset, many=True)
        return Response(serializer.data)

    def update(self, request, pk=None, project_pk=None):
        print(request.data['result'])

    def partial_update(self, request, *args, **kwargs):
        instance = self.queryset.get(pk=kwargs.get('pk'))
        serializer = self.serializer_class(instance, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)