Thursday, June 8, 2017

Upload image file using django rest framework in a single page application

Leave a Comment

I am trying to upload image using Vuejs and Django, but I can't figure out how to solve it.

This is the django side:

class UserDetail(models.Model):     user = models.OneToOneField(User)     profile_picture = models.ImageField(upload_to=create_file_path)  class UserDetailSerializer(serializers.ModelSerializer):     class Meta:         model = UserDetail         fields = '__all__'  class UserDetailViewSet(viewsets.ModelViewSet):     queryset = UserDetail.objects.all()     serializer_class = UserDetailSerializer     permission_classes = [AllowAny]      @detail_route(permission_classes=[AllowAny], methods=['POST'], parser_classes=[FormParser, MultiPartParser])     def create_or_update_profile_picture(self, request):         user = request.user         #         # how to create or update user detail profile picture ?         # 

I am posting the data this way from Vuejs:

changeProfilePicture() {     const file_input = document.getElementById('display_profile_image');     const img = file_input.files[0];     let formData = new FormData();     formData.append("profile_picture", img);     const url = this.$store.state.website + '/api/accounts/user-detail/none/create_or_update_profile_picture/';     this.$http.post(url, formData)         .then(function (response) {             this.$store.dispatch('getUserDetail');         })         .catch(function (response) {             console.log(response);         }); } 

How can I use the post data to create or update the request.user's profile_picture with Django and django rest framework inside the model viewset class, using default methods (create/update/partial_update) or by creating a new detail route?

2 Answers

Answers 1

here is example in official documentation:

http://www.django-rest-framework.org/api-guide/parsers/#fileuploadparser

Answers 2

Assuming your JS posts the request using 'multipart/form-data' (check this), you should be able to upload the image file when creating or updating the user. Also, make sure you send CSRF Token.

To be able to set the logo on its own, a detailed_route is a good way using a serializer limited to the logo. In the detailed route, if you want to upload log for logged in user (I saw you put none as an id), you can check that in the detail route before calling get_object which will get the userdetail instance.

class UserLogoSerializer(serializers.ModelSerializer):     class Meta:         model = UserDetail         fields = ['profile_picture']   class UserDetailViewSet(viewsets.ModelViewSet):     queryset = UserDetail.objects.all()     serializer_class = UserDetailSerializer     permission_classes = [AllowAny]      @detail_route(methods=['post'])     def set_profile_picture(self, request, pk=None, format=None):         if pk in ['none', 'self']: # shortcut to update logged in user without looking for the id             try:                 userdetail = self.get_queryset().get(user=request.user)             except UserDetail.DoesNotExist:                 userdetail = None         else:             userdetail = self.get_object()          serializer = serializers.UserLogoSerializer(userdetail, data=request.data)         if serializer.is_valid():             serializer.save()             return Response(serializer.data)                      return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

If I recall correctly, permission_classes are the one set on the Viewset by default, and the default parsers should do the job.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment