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
?
In Django, a default database is automatically created for you. All you have to do is add the tables called models. The upload_to tells Django to store the photo in a directory called pics under the media directory. The list_display list tells Django admin to display its contents in the admin dashboard.
Its main benefit is that it makes serialization much easier. Django REST framework is based on Django's class-based views, so it's an excellent option if you're familiar with Django. It adopts implementations like class-based views, forms, model validator, QuerySet, and more.
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 love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With