Django Rest Framework:通过 AJAX 上传文件
Posted
技术标签:
【中文标题】Django Rest Framework:通过 AJAX 上传文件【英文标题】:Django Rest Framework: Upload file via AJAX 【发布时间】:2015-11-29 22:31:17 【问题描述】:我有一个视图和序列化器:
class UserView(generics.RetrieveUpdateAPIView):
model = get_user_model()
serializer_class = UserProfileSerializer
permission_classes = (permissions.IsAuthenticated,)
def get_object(self, *args, **kwargs):
return self.request.user
class UserImageSerializer(serializers.ModelSerializer):
class Meta:
model = get_user_model()
fields = ('image',)
它们与 httpie 配合得很好:
http -f put localhost:8000/accounts/api/image/ "Authorization: Token mytoken" image@~/Downloads/test.jpg
HTTP/1.0 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Date: Thu, 03 Sep 2015 22:50:33 GMT
Server: WSGIServer/0.2 CPython/3.4.3
Vary: Accept
X-Frame-Options: SAMEORIGIN
"image": "http://localhost:8000/media/accounts/user_images/test.jpg"
我的图片已上传并显示在管理员中。
现在我希望能够使用 AJAX 上传文件,但它显然不想工作:
<form action="http://localhost:8000/accounts/api/image/"
method="put"
enctype="multipart/form-data">
<input name="image" type="file">
<input type="submit">
</form>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
$('form').submit(function(e)
var formData = new FormData($(this));
$.ajax(
url: $(this).attr('action'),
type: $(this).attr('method'),
data: formData,
headers: 'Authorization': 'Token mytoken',
cache: false,
contentType: false,
processData: false,
success: function() alert('it works') ,
);
e.preventDefault();
);
</script>
现在,我的“它有效”警报出现了。我知道表单正在提交到正确的位置,我可以在 Django 开发服务器中看到它被请求为 PUT 并且它以 200 响应(与 httpie 的响应相同):
[03/Sep/2015 22:47:23] "PUT /accounts/api/image/ HTTP/1.1" 200 77
但文件似乎没有上传,也没有显示在管理中。
我没有想法。
【问题讨论】:
我认为您可能发送了错误的内容类型。根据api.jquery.com/jquery.ajax/#jQuery-ajax-settings,你应该指定contentType: 'multipart/form-data'
上传文件。
@dukebody,我很快就试过了,但它给了我一个 400 Bad Request 并出现此错误:detail: "Multipart form parse error - Invalid boundary in multipart: None"
对不起,我错了。见***.com/questions/9622901/… 和***.com/questions/2320069/jquery-ajax-file-upload
【参考方案1】:
好的,我无法准确解释原因,但似乎单独使用 var formData = new FormData($(this));
是不够的,需要明确附加,原因是什么?如果有人可以解释,请做。
工作代码:
<form action="http://localhost:8000/accounts/api/image/"
method="put"
enctype="multipart/form-data">
<input name="image" type="file" id="image">
<input type="submit">
</form>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
$('form').submit(function(e)
var formData = new FormData($(this));
formData.append('image', $('#image')[0].files[0]);
$.ajax(
url: $(this).attr('action'),
type: $(this).attr('method'),
data: formData,
headers: 'Authorization': 'Token mytoken',
cache: false,
contentType: false,
processData: false,
success: function() alert('it works') ,
);
e.preventDefault();
);
</script>
【讨论】:
FormData 在其构造函数中需要非 jQuery 对象。如果你像这样var formData = new FormData($(this)[0]);
初始化你的formData,它应该被正确初始化,然后你不需要在下一行追加。
$(this)[0] == this以上是关于Django Rest Framework:通过 AJAX 上传文件的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 Django Rest Framework 返回嵌套的 json