javascript - 使用 fetch api 上传图像在 django 中不起作用
问题描述
我的views.py文件
def change_profile_picture(request):
if not request.user.is_authenticated:
return JsonResponse({"status": "403", "msg": "Unauthorized request"})
if request.method == 'POST':
if request.is_ajax():
form = UploadPictureForm(request.POST)
if form.is_valid():
customuser = request.user.customuser
customuser.picture = form.cleaned_data['picture']
customuser.save()
return JsonResponse(
{
"status": "200",
"msg": "Successful",
"data": f"{customuser.picture.url}"
}
)
else:
return JsonResponse({"status": "400", "msg": "invalid form"})
else:
return JsonResponse({"status": "401", "msg": "Bad request"})
else:
return JsonResponse({"status": "403", "msg": "invalid request method"})
forms.py
class UploadPictureForm(forms.Form):
picture = forms.ImageField(
label="Profile picture"
)
Javascript代码:
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
$('.upload-btn').on('click', () => {
document.getElementById('id_picture').click();
})
$('.close-btn').on('click', () => {
document.getElementById('profile-picture').src = $('#profile-picture').data('target');
document.getElementById('submit-picture').style.visibility = 'hidden';
})
$('#submit-picture').on('click', () => {
var picture = document.querySelector('input[type="file"]');
var formData = new FormData();
formData.append('csrfmiddlewaretoken', getCookie('csrftoken'));
formData.append('picture', picture.files[0]);
fetch('/auth/change-profile-picture/', {
method: 'POST',
body: formData,
cache: 'default',
mode: 'cors',
credentials: 'include',
headers: {
"X-Requested-With": "XMLHttpRequest",
}
})
.then((res) => res.json())
.then((data) => {
if(data.status === '200') {
document.getElementById('profile-picture').src = data.data;
alert("done");
} else {
console.log(data.msg);
}
})
.catch((err) => console.log(err))
})
HTML 模板:
<div class="col-md-6 order-sm-12 my-5">
<p class="upload-btn"><i class="fa fa-camera"></i> Edit profile picture</p>
<p class="close-btn"><i class="fas fa-times"></i> Reset</p>
<img class="profile-img" id="profile-picture" data-target="{% if user.customuser.picture %}{{ user.customuser.picture.url }}{% endif %}" src="{% if user.customuser.picture %}{{ user.customuser.picture.url }}{% endif %}" />
{% if user == request.user %}
<input id="id_picture" style="visibility:hidden;" name="picture" type="file" accept="image/*" required onchange="document.getElementById('profile-picture').src = window.URL.createObjectURL(this.files[0]);document.getElementById('submit-picture').style.visibility = 'visible';">
<button class="btn vizew-btn w-100 my-3" style="visibility:hidden;" id="submit-picture">Change profile picture</button>
{% endif %}
</div>
视图函数,change_profile_picture
返回invalid form
,我不知道为什么。到目前为止,我注意到图片文件实际上并没有使用 fetch api 发送。我也尝试过从使用 Javascript 提交更改为使用普通 HTML 表单标签,它仍然给出相同的错误。将继承的表单类更改为 ModelForm 只会使用默认值填充该字段。我如何解决它?
解决方案
我在 change_profile 视图中发现,我用提交的数据初始化表单,我没有request.FILES
像这样填充表单:
<code>
if request.method == 'POST':
if request.is_ajax():
form = UploadPictureForm(request.POST, request.FILES)
<more code>
推荐阅读
- sql-server - SQL Server sp_send_dbmail 未将电子邮件中的正文发送到短信
- javascript - 引导日期/选择器未显示
- vue.js - Vue-Analytics 不起作用(注意:我需要根据主机名更改 id)
- javascript - math.floor 和 math.radom 是一个索引
- scala - 根据列表中定义的列过滤数据框
- android - 如何在 android 中使用 MFCC TarsosDSP 和麦克风
- python - Python ncurses addstr 预期字节或 str,得到 int
- grails - 在列表中包含的值中定义固定位置
- javascript - IF 在地图箭头函数内
- javascript - webpack 文件加载器输出损坏的图像