【问题标题】:Django/Tastypie Image upload - Invalid boundary in multipart: None?Django/Tastypie 图像上传 - 多部分中的边界无效:无?
【发布时间】:2013-12-09 06:10:32
【问题描述】:

我是 python/django/tastypie 的新手,正在尝试上传文件。我遇到了一个非常奇怪的(对我来说是)错误,我似乎无法弄清楚。每当我尝试通过我的 REST 客户端(CocoaRest 客户端)上传照片时,它都会出现以下错误:

{
  "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"
}

我设置了标题“Content-Type: multipart/form-data”,并在文件选项卡中添加了一个文件。

这是我从客户端调用的方法:

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)

当我在 if('image' in request.FILES) 之前执行 print(request) 时,我没有收到同样的错误,它实际上跳转到我的 else 并打印“未找到图像”,这很奇怪不会以同样的方式爆炸。

我不确定我还需要做什么,添加更多标题?设置一个“边界”(不确定那是什么)......非常感谢任何帮助。我愿意尝试并在这里发布结果以获得更好的帮助。谢谢!

【问题讨论】:

    标签: django python-2.7 tastypie multipartform-data


    【解决方案1】:

    最终创建了一个新的 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)
    

    在使用PIL换图后也使用amazon s3来存储图片。

    【讨论】:

      猜你喜欢
      • 2023-03-03
      • 1970-01-01
      • 2013-09-06
      • 2016-05-05
      • 2021-12-07
      • 2013-02-19
      • 2013-10-08
      • 2016-03-23
      • 1970-01-01
      相关资源
      最近更新 更多