2

我正在尝试通过 Multipart/Form-Data 表单和 Tastypie API 上传文件,但遇到了一些问题:

我的模型:

class Client(models.Model):
    account = models.ForeignKey(Account)
    client_image = models.FileField(upload_to=client_image_path, default="/assets/img/default-user-image.png", blank=True, null=True)
    client_image_thumb = models.FileField(upload_to=client_image_thumb_path, default="/assets/img/default-user-image.png", blank=True, null=True)

我正在使用 Tastypie Issue#42 中概述的自定义反序列化方法:

class MultipartResource(object):
    def deserialize(self, request, data, format=None):
        if not format:
            format = request.META.get('CONTENT_TYPE', 'application/json')

        if format == 'application/x-www-form-urlencoded':
            return request.POST

        if format.startswith('multipart'):
            data = request.POST.copy()
            data.update(request.FILES)
            return data

        return super(MultipartResource, self).deserialize(request, data, format)

    def put_detail(self, request, **kwargs):
        if request.META.get('CONTENT_TYPE').startswith('multipart') and \
                not hasattr(request, '_body'):
            request._body = ''

        return super(MultipartResource, self).put_detail(request, **kwargs)

这是我对应的ModelResource:

class ClientResource(MultipartResource, ModelResource):
    account = fields.ForeignKey(AccountResource, 'account')

    class Meta():
        queryset = Client.objects.all()
        always_return_data = True
        resource_name = 'account/clients/client-info'
        authorization = AccountLevelAuthorization()
        list_allowed_methods = ['get','post','put','delete','patch']
        detail_allowed_methods = ['get', 'post', 'put', 'delete','patch']
        authentication = ApiKeyAuthentication()
        filtering = {
            'username': ALL,
        }

如果我使用内容类型应用程序/JSON 进行 POST 并且不包含 client_image 字段,它将成功创建一个新的客户端对象。这表明模型/资源正在正常工作。

但是,当我尝试使用 Multipart/Form-Data 内容类型时,我可以看到它通过此有效负载适当地通过了我的反序列化器:

------WebKitFormBoundaryp0Q7Q9djlsvVGwbb
Content-Disposition: form-data; name="{%0D%0A%22account%22"

"/api/v1/account/account-info/21/",

------WebKitFormBoundaryp0Q7Q9djlsvVGwbb
Content-Disposition: form-data; name="client_image"; filename="donavan.jpg"
Content-Type: image/jpeg

------WebKitFormBoundaryp0Q7Q9djlsvVGwbb--

我在调试时也看到了这个 QueryDict,它正确显示了 InMemoryUploadedFile:

<QueryDict: {u'client_image': [<InMemoryUploadedFile: donavan.jpg (image/jpeg)>], u'{%0D%0A%22account%22': [u'"/api/v1/account/account-info/21/"']}>

但我不断收到此错误:

{ error_message:“”回溯:“回溯(最近一次通话最后一次):文件“/Users/stevewirig/Documents/www/vu/venv/lib/python2.7/site-packages/tastypie/resources.py”,第 202 行,在包装响应 = 回调(请求,*args,**kwargs)文件“/Users/stevewirig/Documents/www/vu/venv/lib/python2.7/site-packages/tastypie/resources.py”,第 440 行, 在 dispatch_list 返回 self.dispatch('list', request, **kwargs) 文件 "/Users/stevewirig/Documents/www/vu/venv/lib/python2.7/site-packages/tastypie/resources.py",第 472 行,在调度响应 = 方法(请求,**kwargs)文件“/Users/stevewirig/Documents/www/vu/venv/lib/python2.7/site-packages/tastypie/resources.py”中,第 1328 行,在 post_list updated_bundle = self.obj_create(bundle, **self.remove_api_resource_names(kwargs)) 文件“/Users/stevewirig/Documents/www/vu/venv/lib/python2.7/site-packages/tastypie/resources.py”,第 2104 行,在 obj_create bundle = self.full_hydrate(bundle)文件“/Users/stevewirig/Documents/www/vu/venv/lib/python2.7/site-packages/tastypie/resources.py”,第 890 行,full_hydrate 值 = field_object.hydrate(bundle) 文件“/Users/ stevewirig/Documents/www/vu/venv/lib/python2.7/site-packages/tastypie/fields.py”,第 732 行,水合物值 = super(ToOneField, self).hydrate(bundle) 文件“/Users/ stevewirig/Documents/www/vu/venv/lib/python2.7/site-packages/tastypie/fields.py”,第 165 行,水合物 elif self.attribute 和 getattr(bundle.obj, self.attribute, None):文件“/Users/stevewirig/Documents/www/vu/venv/lib/python2.7/site-packages/django/db/models/fields/related.py”,第 343 行,在得到提高 self.field.rel.to.DoesNotExist DoesNotExist " }

有什么想法可以打破吗?提前致谢!

4

2 回答 2

0

当我在未提供必要字段的情况下发布数据时,这发生在我身上。发布时必须提供那些不能为空的字段。

于 2013-06-13T22:28:06.547 回答
0

初始化序列化器如下:

serializer = Serializer(formats=['json'])

于 2020-07-21T11:52:35.013 回答