Django Rest Framework将文件上传到方法

时间:2014-10-31 11:24:57

标签: python django django-rest-framework

所以我一直试图将文件上传到使用DRF的方法到目前为止没有运气。

我能够使用ModelViewSet上传到(FormParser, MultiPartParser,)没有任何问题,但我真的需要在http://localhost:8000/api/v1/women/{pk}/upload_avatar/这样的地方使用它,我想首先通过以下方式过滤女人id并上传到她的头像(这是多媒体模型的外键)。我尝试使用嵌套资源库而没有运气。

到目前为止,我已经在我的模型集中了:

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)

我的模特:

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)

基本上我想知道这是否是我正在采取的正确路径,如果是,我怎样才能正确保存模型中的上传文件?

2 个答案:

答案 0 :(得分:7)

以下是我为克服这个问题所做的一些代码。虽然凯文布朗回答可能有效,但我发现我的代码有点“轻松”#34;的方法:

    @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()

答案 1 :(得分:0)

任何上传的文件都应该在request.FILES中提供,这是一个字典,由上传时使用的字段键入。获得该文件后,处理它与其他任何uploaded file in Django类似。

如果可以,我会使用第二个包装Multimedia模型的序列化程序,以便通过Django REST Framework自动完成图像验证和保存。有an ImageField会自动验证您可以在序列化程序上使用的Pillow图像。