Django Rest Framework:通过iOS Swift客户端上载文件处理错误

时间:2018-10-16 04:23:31

标签: swift django django-rest-framework

在处理iOS Swift客户端上传文件时遇到问题。我在下面完全描述

我的模特:

def avatar_photo_upload(instance, filename):
    if filename:
        ext = filename.split('.')[-1]
        filename = 'avatar.%s' % (ext)
    else:
        filename = 'avatar.jpg'
    return "avatar/%s/%s" %('profile', filename)

class Profile(models.Model):
    avatar = models.FileField("Uploaded avatar of profile", storage=OverwriteStorage(), upload_to=avatar_photo_upload, null=True, blank=True)

我的序列化器:

class PhotoUpdateSerializer(ModelSerializer):
    file = ImageField(max_length=100000, allow_empty_file=False, use_url=False)
    class Meta:
        model = Profile
        fields = [
            'file',
        ]

我的观点:

class UploadPhotoAPIView(ModelViewSet):
    serializer_class = PhotoUpdateSerializer
    queryset = Profile.objects.all()
    parser_classes = (JSONParser, MultiPartParser, FormParser,)
    permission_classes = (IsAuthenticated,)

    def upload_avatar(self, request):
        serializer = self.get_serializer(data=request.data, context={"request": request})
        logger.info('Information incoming!')
        if serializer.is_valid():
            profile = Profile.objects.get(user=request.user)
            profile.avatar = request.FILES.get('file')
            profile.save()
            return Response({ 'status': 'ok', 'avatar': get_avatar_url(request, '300x300', 'user', profile.user_id) }, status=status.HTTP_201_CREATED)
        else:
            logger.error('Toan Error' + str(serializer.errors))
            return Response(serializer.errors, status=status.HTTP_501_NOT_IMPLEMENTED)

最后,这是我的网址:

url(r'^account/upload_avatar/$', UploadPhotoAPIView.as_view({'post': 'upload_avatar'}))

我相信我会一直做下去,直到在iOS Swift中测试API,它都会返回错误:

客户请求

func uploadImage(image:UIImage) {
    let imageData:NSData = UIImageJPEGRepresentation(image, 100)
    SRWebClient.POST("https://api.com/api/v1/users/account/upload_avatar/")
        .data(imageData, fieldName:"file", data: ["filename":"avatar","ext":".jpg"])
        .send({(response:AnyObject!, status:Int) -> Void in
            // process success response
        },failure:{(error:NSError!) -> Void in
            // process failure response
        })
    }

错误回溯:

  

[请求]:POST   https://api.com/api/v1/users/account/upload_avatar/   [回应]:{URL:   https://api.com/api/v1/users/account/upload_avatar/} {   状态码:501,标题{       “内容长度” =(           84       );       “内容类型” =(           “应用程序/ json”       );       日期=(           “ 2018年10月10日星期三10:41:31 GMT”       );       服务器=(           云耀斑       );       变化=(           起源       );       允许=(           “发布,选项”       );       “ cf-ray” =(           “ 46787998dfaa8502-HKG”       );       “ expect-ct” =(           “ max-age = 604800,report-uri = \” https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct \“”       );       “ x-frame-options” =(           SAMEORIGIN       ); }} [数据]:84个字节[结果]:成功:{       文件=(           “提交的数据不是文件。请检查表单上的编码类型。”       ); } [时间轴]:时间轴:{“请求开始时间”:560860890.985,“初始响应时间”:560860891.099,“请求完成时间”:   560860891.100,“序列化完成时间”:560860891.100,“延迟”:0.114秒,“请求持续时间”:0.115秒,“序列化   持续时间”:0.000秒,“总持续时间”:0.115秒}▿请求:   可选的       ▿一些:https://api.com/api/v1/users/account/upload_avatar/         ▿网址:可选           ▿一些:https://api.com/api/v1/users/account/upload_avatar/             -_url:https://api.com/api/v1/users/account/upload_avatar/         -cachePolicy:0         -timeoutInterval:60.0         -mainDocumentURL:无         -networkServiceType:__C.NSURLRequestNetworkServiceType         -allowCellularAccess:true         Method httpMethod:可选           -一些:“ POST”         ▿allHTTPHeaderFields:可选>           ▿一些:2要素             ▿0:2个元素               -键:“内容类型”               -值:“应用程序/ x-www-form-urlencoded; charset = utf-8”             ▿1:2元素               -键:“授权”                - 值: “智威汤逊eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoyMSwidXNlcm5hbWUiOiJkdW9uZ251aGFiYW5nIiwiZXhwIjoyNDAzMTY4MDU5LCJlbWFpbCI6ImRyYWZ0bGlnb25ncXVhbjdAZ21haWwuY29tIn0.ZfDBOaAhKsRSpZl3mP87doR34UtlGISfeqJYlJnxcVI”         B httpBody:可选           ▿一些:105字节             -数量:105             ▿指针:0x00006000025d2510               -指针值:105553155925264         -httpBodyStream:无         -httpShouldHandleCookies:是         -httpShouldUsePipelining:false响应:可选       -一些:{网址:https://api.com/api/v1/users/account/upload_avatar/} {   状态码:501,标题{       “内容长度” =(           84       );       “内容类型” =(           “应用程序/ json”       );       日期=(           “ 2018年10月10日星期三10:41:31 GMT”       );       服务器=(           云耀斑       );       变化=(           起源       );       允许=(           “发布,选项”       );       “ cf-ray” =(           “ 46787998dfaa8502-HKG”       );       “ expect-ct” =(           “ max-age = 604800,report-uri = \” https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct \“”       );       “ x-frame-options” =(           SAMEORIGIN       );数据:可选       ▿一些:84字节         -数量:84         ▿指针:0x00006000025d0c00           -指针值:105553155918848▿结果:成功:{       文件=(           “提交的数据不是文件。请检查表单上的编码类型。”       ); }       ▿成功:1个要素         ▿0:2个元素           -键:文件           ▿值:1个元素             -0:提交的数据不是文件。检查表单上的编码类型。 ▿时间轴:时间轴:{“请求开始时间”:   560860890.985,“初始响应时间”:560860891.099,“请求完成时间”:560860891.100,“序列化完成时间”:   560860891.100,“等待时间”:0.114秒,“请求持续时间”:0.115秒,“序列化持续时间”:0.000秒,“总持续时间”:0.115秒}       -requestStartTime:560860890.984645       -initialResponseTime:560860891.099072       -requestCompletedTime:560860891.099792       -serializationCompletedTime:560860891.099964       -延迟时间:0.11442697048187256       -requestDuration:0.11514699459075928       -序列化持续时间:0.00017201900482177734       -totalDuration:0.11531901359558105 _ _metrics:可选       -一些:(任务间隔)<_NSConcreteDateInterval:0x600000b68980>(开始日期)2018-10-10 10:41:30 +0000 +(持续时间)0.115085秒=   (结束日期)2018-10-10 10:41:31 +0000(重定向计数)0(交易   指标)(请求){URL:   https://api.com/api/v1/users/account/upload_avatar/}   (响应){URL:   https://api.com/api/v1/users/account/upload_avatar/} {   状态码:501,标题{       “内容长度” =(           84       );       “内容类型” =(           “应用程序/ json”       );       日期=(           “ 2018年10月10日星期三10:41:31 GMT”       );       服务器=(           云耀斑       );       变化=(           起源       );       允许=(           “发布,选项”       );       “ cf-ray” =(           “ 46787998dfaa8502-HKG”       );       “ expect-ct” =(           “ max-age = 604800,report-uri = \” https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct \“”       );       “ x-frame-options” =(           SAMEORIGIN       ); }}(获取开始)2018-10-10 10:41:30 +0000(域查找开始)(null)(域查找结束)(null)(连接开始)(null)   (安全连接开始)(空)(安全连接结束)(空)   (连接结束)(空)(请求开始)2018-10-10 10:41:30 +0000   (请求结束)2018-10-10 10:41:30 +0000(响应开始)2018-10-10   10:41:31 +0000(响应结束)2018-10-10 10:41:31 +0000(协议   名称)h2(代理连接)否(重用连接)是(获取类型)   网络负载

问题是什么,它来自服务器还是客户端?请给我一个建议。预先感谢!

1 个答案:

答案 0 :(得分:1)

您必须将内容类型作为多部分表单数据进行传递。

class UploadPhotoAPIView(ModelViewSet):
   serializer_class = PhotoUpdateSerializer
   queryset = Profile.objects.all()
   parser_classes = (JSONParser, MultiPartParser, FormParser,)
   permission_classes = (IsAuthenticated,)

  def upload_avatar(self, request):
    serializer = self.get_serializer(instance=Profile.objects.get(user=request.user), data=request.data, context={"request": request})
    logger.info('Information incoming!')
    if serializer.is_valid():
        serializer.save()
        return Response({ 'status': 'ok', 'avatar': get_avatar_url(request, '300x300', 'user', profile.user_id) }, status=status.HTTP_201_CREATED)
    else:
        logger.error('Toan Error' + str(serializer.errors))
        return Response(serializer.errors, status=status.HTTP_501_NOT_IMPLEMENTED)

在客户端以多部分形式发送数据