在单页面应用程序中使用django rest框架上载图像文件

Rob*_*bin 11 django django-rest-framework

我正在尝试使用Vuejs和Django上传图像,但我无法弄清楚如何解决它.

这是django方面:

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 ?
        #
Run Code Online (Sandbox Code Playgroud)

我以这种方式从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);
        });
}
Run Code Online (Sandbox Code Playgroud)

如何使用post数据request.user在模型视图集类中使用Django和django rest框架创建或更新profile_picture,使用默认方法(create/update/partial_update)或创建新的detail route

Mic*_*oni 6

假设你的JS帖子使用“请求multipart/form-data”(检查),你应该能够创建或更新时,用户上传的图像文件。另外,请确保您发送CSRF令牌

为了能够自行设置徽标,detailed_route使用限制于徽标的序列化器是一种好方法。在详细路径中,如果要上载已登录用户的日志(我看到您输入的none是id),则可以在调用get_object该详细路径之前检查该详细路径,以获取userdetail实例。

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)
Run Code Online (Sandbox Code Playgroud)

如果我没permission_classes记错的话,默认情况下是Viewset上的那个,默认解析器应该可以完成这项工作。