2013-12-09 44 views
3

我是新來的python/django/tastypie,我正在嘗試做文件上傳。我感到很奇怪(對我來說)錯誤,我似乎無法弄清楚。每當我試着通過其他客戶端(CocoaRest客戶端),它的炸彈,出現以下錯誤上傳照片:Django/Tastypie圖片上傳 - 多部分無效邊界:無?

{ 
    "error_message" : "Invalid boundary in multipart: None", 
    "traceback" : "Traceback (most recent call last):\n\n File \"/Users/crown/Documents/Sources/Virtualenvs/GOCApi/lib/python2.7/site-packages/tastypie/resources.py\", line 195, in wrapper\n response = callback(request, *args, **kwargs)\n\n File \"/Users/crown/Documents/Sources/GOCApi/api/resources/member.py\", line 85, in post_profile_picture\n if('image' in request.FILES):\n\n File \"/Users/crown/Documents/Sources/Virtualenvs/GOCApi/lib/python2.7/site-packages/django/core/handlers/wsgi.py\", line 214, in _get_files\n self._load_post_and_files()\n\n File \"/Users/crown/Documents/Sources/Virtualenvs/GOCApi/lib/python2.7/site-packages/django/http/request.py\", line 217, in _load_post_and_files\n self._post, self._files = self.parse_file_upload(self.META, data)\n\n File \"/Users/crown/Documents/Sources/Virtualenvs/GOCApi/lib/python2.7/site-packages/django/http/request.py\", line 176, in parse_file_upload\n parser = MultiPartParser(META, post_data, self.upload_handlers, self.encoding)\n\n File \"/Users/crown/Documents/Sources/Virtualenvs/GOCApi/lib/python2.7/site-packages/django/http/multipartparser.py\", line 69, in __init__\n raise MultiPartParserError('Invalid boundary in multipart: %s' % boundary)\n\nMultiPartParserError: Invalid boundary in multipart: None\n" 
} 

我已經報頭中設置「內容類型:多部分/表單數據」,以及有一個文件添加到文件選項卡。

這裏是我的方法,我從客戶端調用:

def post_profile_picture(self, request, *args, **kwargs): 
     if(request.method == 'POST'): 
      if(str(request.META['CONTENT_TYPE']) != "multipart/form-data"): 
       return self.create_response(request, HelperMethods.api_return_msg("Unsupported media type"), response_class=http.HttpBadRequest) 
      else: 
       if('image' in request.FILES): 

        #bunch of code removed 

        return self.create_response(request, {"profile_img" : profile_img_key_name, "thumb_img" : thumb_img_key_name}, response_class=http.HttpResponse) 
       else: 
        return self.create_response(request, HelperMethods.api_return_msg("No image found"), response_class=http.HttpBadRequest) 
     else: 
      return self.create_response(request, HelperMethods.api_return_msg("Method not allowed"), response_class=http.HttpMethodNotAllowed) 

當我如果(在request.FILES「圖像」)前執行打印(要求),我沒有得到同樣的錯誤,它實際上跳到我的其他地方並打印出「找不到圖像」,這很奇怪,它不會以同樣的方式炸燬。

我不知道還有什麼我需要做的,添加更多的標題?設置一個「邊界」(不知道這是什麼)...任何幫助,非常感謝。我願意嘗試並在此發佈結果以獲得更好的幫助。謝謝!

回答

4

結束製作一個新的ModelResource,然後將Content-Type設置爲:multipart/form-data;邊界=邊界

花了我一段時間才弄清楚,即使OP是昨天,10小時是一大堆谷歌搜索和試驗和錯誤...... smdh。

這裏是模型資源:

from tastypie import http, fields 
from django.conf.urls import url 
from tastypie.resources import ModelResource 
from api.helper_methods import HelperMethods 
from django.conf import settings 
from boto.s3.connection import S3Connection 
from boto.s3.key import Key 
import cStringIO 
from PIL import Image, ImageOps 

class FileUploadResource(ModelResource): 
    img = fields.FileField(attribute="img", null=True, blank=True) 
    class Meta: 
     allowed_methods = 'post' 
     resource_name = 'file_upload' 
     include_resource_uri = False 

    def prepend_urls(self): 
     return [ 
      url(r"^(?P<resource_name>%s)/$" % self._meta.resource_name, self.wrap_view('get_profile_picture'), name="api_get_profile_picture"), 
      url(r"^(?P<resource_name>%s)/profile_picture/$" % self._meta.resource_name, self.wrap_view('post_profile_picture'), name="api_post_profile_picture"), 
      ] 

    def get_profile_picture(self, request, **kwargs): 
     return self.create_response(request, HelperMethods.api_return_msg("Bad requested"), response_class=http.HttpBadRequest) 

    def post_profile_picture(self, request, **kwargs): 
     if(request.method == 'POST'): 
      if "multipart/form-data" not in str(request.META['CONTENT_TYPE']): 
       return self.create_response(request, HelperMethods.api_return_msg("Unsupported media type"), response_class=http.HttpBadRequest) 
      else: 
       if('image' in request.FILES): 
        upload = request.FILES['image'] 
        main_img = Image.open(upload) 

        profile_img = main_img.resize((200,200), Image.ANTIALIAS) 
        profile_img_io = cStringIO.StringIO() 
        profile_img.save(profile_img_io, 'PNG', quality=85) 

        thumb_img = main_img.resize((80,80), Image.ANTIALIAS) 
        thumb_img_io = cStringIO.StringIO() 
        thumb_img.save(thumb_img_io, 'PNG', quality=85) 

        conn = S3Connection(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY) 
        bucket = conn.get_bucket(settings.BUCKET_NAME) 

        profile_img_key_name = HelperMethods.generate_pic_key() + ".png" 
        profile_img_key = Key(bucket) 
        profile_img_key.key = profile_img_key_name 
        profile_img_key.set_contents_from_string(profile_img_io.getvalue()) 
        profile_img_key.make_public() 

        thumb_img_key_name = HelperMethods.generate_pic_key() + ".png" 
        thumb_img_key = Key(bucket) 
        thumb_img_key.key = thumb_img_key_name 
        thumb_img_key.set_contents_from_string(thumb_img_io.getvalue()) 
        thumb_img_key.make_public() 

        return self.create_response(request, {"profile_img" : profile_img_key_name, "thumb_img" : thumb_img_key_name}, response_class=http.HttpResponse) 
       else: 
        return self.create_response(request, HelperMethods.api_return_msg("No image found"), response_class=http.HttpBadRequest) 
     else: 
      return self.create_response(request, HelperMethods.api_return_msg("Method not allowed"), response_class=http.HttpMethodNotAllowed) 

它還使用Amazon S3的存儲圖像被用於後PIL改變圖像。