Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework upload file to a method

So i have been trying to upload a file to a method using DRF with no luck so far.

I was able to upload to a ModelViewSet using (FormParser, MultiPartParser,) with no problems, but i really need to use it in something like this http://localhost:8000/api/v1/women/{pk}/upload_avatar/ where i want to first filter the woman by id and upload to her avatar (which is a foreign key to a multimedia model). I tried using a nested resource library with no luck.

So far i have in my modelviewset:

class WomenNativePassportViewSet(viewsets.ModelViewSet):
    queryset = Women.objects.all()
    serializer_class = WomenNativePassportSerializer
    authentication_classes = (NoAuthentication,)
    permission_classes = (AllowAny,)
    parser_classes = (FormParser, MultiPartParser,)

    @detail_route(
        methods=['post', 'put', 'patch', 'get'], permission_classes=[AllowAny],
        authentication_classes=[NoAuthentication], serializer_class=MultimediaSerializer,
        parser_classes=(FormParser, MultiPartParser,)
    )
    def upload_avatar(self, request, pk=None, *args, **kwargs):
        if 'POST' in request._method or 'PATCH' in request._method:
            # Write code to save the file??
        else:
            multimedia = Multimedia.objects.filter(user_profiles_avatares__pk=pk)
            page = self.paginate_queryset(multimedia)
            serializer = self.get_pagination_serializer(page)
        return Response(serializer.data)

My models:

class Women(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL)
    avatar = models.ForeignKey(
        'core.Multimedia', blank=True, null=True,
        related_name='user_profiles_avatares'
    )

class Multimedia(models.Model):
    file = models.FileField(upload_to=upload_to, null=True, blank=True)
    thumbnail = models.FileField(upload_to=upload_to, null=True, blank=True)

Basically i want to know if this is the right path i am taking, and if yes how can i properly save the uploaded file in the model??

like image 426
psychok7 Avatar asked Oct 31 '14 11:10

psychok7


People also ask

How do I upload files using Django REST Framework?

So you have two choices: let ModelViewSet and ModelSerializer handle the job and send the request using content-type=multipart/form-data; set the field in ModelSerializer as Base64ImageField (or) Base64FileField and tell your client to encode the file to Base64 and set the content-type=application/json.

How do I upload files to AWS s3 using Django REST Framework?

Building a simple Django Rest API application Execute the commands below to set up the project. Add the code snippet below to urls.py file in the dropboxer project directory. Create serializers.py and urls.py files in the uploader app. In models.py file, we create a simple model that represents a single file.

What is JSONParser Django?

JSONParser. Parses JSON request content. request. data will be populated with a dictionary of data. .media_type: application/json.

What is renderers in Django REST Framework?

The rendering process takes the intermediate representation of template and context, and turns it into the final byte stream that can be served to the client. REST framework includes a number of built in Renderer classes, that allow you to return responses with various media types.


1 Answers

Here is some code of what i did to overcome this problem. Although Kevin Brown answer probably works, i find my code a little "easier" approach:

    @detail_route(
        methods=['post', 'put', 'patch', 'get'], permission_classes=[AllowAny],
        authentication_classes=[NoAuthentication], serializer_class=MultimediaSerializer,
        parser_classes=(FormParser, MultiPartParser,)
    )
    def upload_avatar(self, request, pk=None):
        # Because we are using nested resources this was the only way i found to
        # upload a file. Maybe there is a better way
        if request.method in ['PATCH', 'POST']:
            avatar = request.FILES.get('avatar')
            if not avatar:
                return Response(status=404)

            try:
                woman = WomenNativePassport.objects.get(pk=pk)
            except WomenNativePassport.DoesNotExist:
                return Response(status=404)
            else:
                request.FILES['thumbnail'] = request.FILES['avatar']
                serializer = AvatarSerializer(
                    data=request.DATA, files=request.FILES
                )
                if serializer.is_valid():
                    woman.avatar.thumbnail.save(str(avatar), File(avatar))
                    return Response(status=204)
                else:
                    return Response(status=404)
        else:
            multimedia = Multimedia.objects.filter(user_profiles_avatares__pk=pk)
            page = self.paginate_queryset(multimedia)
            serializer = self.get_pagination_serializer(page)
            return Response(serializer.data)


# serializer 

class AvatarSerializer(serializers.Serializer):
    thumbnail = serializers.ImageField()
like image 91
psychok7 Avatar answered Sep 29 '22 02:09

psychok7