Ajax 请求期间的 Django 视图 returns None
Django view returns None during Ajax request
我有一个 Django 网络应用程序,我正在尝试发出 ajax 调用以上传大图像。如果我可以上传我正在尝试上传的图像,我将使用 pythonocc 库和 return 读取图像的卷信息。由于这个过程需要很长时间,我正在尝试使用 django-background-tasks 库来完成它。根据我所说的,我尝试拍摄图像并将其发送到视图的 ajax 请求如下。
var data = new FormData();
var img = $('#id_Volume')[0].files[0];
data.append('img', img);
data.append('csrfmiddlewaretoken', '{{ csrf_token }}');
$.ajax({
method: 'POST',
url: '{% url 'data:upload' %}',
cache: false,
processData: false,
contentType: false,
type: 'POST',
data: data,
}).done(function(data) {
});
我的观点将在 Ajax 请求后生效;
def uploadFile(request):
if request.method == 'POST':
file = request.FILES.get('img')
filename = file.name
key = 'media/' + filename
s3_resource = boto3.resource('s3')
bucket = s3_resource.Bucket('bucket')
bucket.put_object(Key=key, Body=file)
new_data = Data(author=request.user)
new_data.save()
data_id = new_data.id
initial = CompletedTask.objects.filter(verbose_name=verbose)
request.session['u_initial'] = len(initial)
verbose = str(request.user) + '_3D'
read_3D(data_id, key, filename, verbose_name = verbose) ###background-task function is called
return redirect('data:uploadStatus')
调用此后台任务函数的视图也应该重定向视图,这将显示上传状态。
def upload_status(request):
customer= str(request.user)
verbose = customer + '_3D'
initial = request.session['u_initial']
if request.is_ajax():
running, completed = get_upload_status(verbose)
context = {
"initial": initial,
"running": running,
"completed": completed,
}
return JsonResponse(context)
return render(request, "file_pending.html")
然而,当我发出 Ajax 请求时,视图给出了 The view data.views.uploadFile didn't return an HttpResponse object. It returned None instead.
错误,因为它没有进入 if request.method == 'POST'
条件。当我从视图中删除该条件行时,它无法获取 img 文件。顺便说一句,这个 uploadFile 视图工作没有任何问题。奇怪的是,当我添加 upload_status 视图并重定向它时,它停止工作了。要还原,我删除了那部分并还原了它,但它仍然没有用。
我该如何解决这个问题?我错过了什么吗?
A. 您应该将查看方法限制为您期望使用的实际方法 the require_http_methods decorator
from django.views.decorators.http import require_POST
@require_POST
def uploadFile(request):
file = request.FILES.get('img')
filename = file.name
key = 'media/' + filename
s3_resource = boto3.resource('s3')
# ....
return redirect('data:uploadStatus')
不使用 POST 调用此端点的方式将收到 405 Method not allowed 响应。更容易调试并弄清问题所在。
B. 确保您在前端的 Ajax 调用遵循重定向。
cache
参数对于 POST 不是必需的(除非您计划用于 IE8)
关于 contentType=false
和 processData=false
:在我看来,这仍然是一个常规的 multipart-formdata 电话。不要这样做,除非你知道你为什么这样做。您的 Django 代码看起来可以很好地处理常规表单数据,无需修改默认行为。
C. 你也必须实现一个错误回调:
}).done(function(data) {
}).fail(function(xhr, text, error) {
console.log(text, error)
});
我想发生的是一些您没有在 JS 代码中处理的错误。
您还没有添加您的设置,所以我不能确定,但我想您没有正确设置 AJAX 的 CSRF 配置。解决此问题的一种方法是将 CSRF cookie 也添加到 AJAX 请求中。 CSRF 表单字段和 cookie 都必须存在。
我有一个 Django 网络应用程序,我正在尝试发出 ajax 调用以上传大图像。如果我可以上传我正在尝试上传的图像,我将使用 pythonocc 库和 return 读取图像的卷信息。由于这个过程需要很长时间,我正在尝试使用 django-background-tasks 库来完成它。根据我所说的,我尝试拍摄图像并将其发送到视图的 ajax 请求如下。
var data = new FormData();
var img = $('#id_Volume')[0].files[0];
data.append('img', img);
data.append('csrfmiddlewaretoken', '{{ csrf_token }}');
$.ajax({
method: 'POST',
url: '{% url 'data:upload' %}',
cache: false,
processData: false,
contentType: false,
type: 'POST',
data: data,
}).done(function(data) {
});
我的观点将在 Ajax 请求后生效;
def uploadFile(request):
if request.method == 'POST':
file = request.FILES.get('img')
filename = file.name
key = 'media/' + filename
s3_resource = boto3.resource('s3')
bucket = s3_resource.Bucket('bucket')
bucket.put_object(Key=key, Body=file)
new_data = Data(author=request.user)
new_data.save()
data_id = new_data.id
initial = CompletedTask.objects.filter(verbose_name=verbose)
request.session['u_initial'] = len(initial)
verbose = str(request.user) + '_3D'
read_3D(data_id, key, filename, verbose_name = verbose) ###background-task function is called
return redirect('data:uploadStatus')
调用此后台任务函数的视图也应该重定向视图,这将显示上传状态。
def upload_status(request):
customer= str(request.user)
verbose = customer + '_3D'
initial = request.session['u_initial']
if request.is_ajax():
running, completed = get_upload_status(verbose)
context = {
"initial": initial,
"running": running,
"completed": completed,
}
return JsonResponse(context)
return render(request, "file_pending.html")
然而,当我发出 Ajax 请求时,视图给出了 The view data.views.uploadFile didn't return an HttpResponse object. It returned None instead.
错误,因为它没有进入 if request.method == 'POST'
条件。当我从视图中删除该条件行时,它无法获取 img 文件。顺便说一句,这个 uploadFile 视图工作没有任何问题。奇怪的是,当我添加 upload_status 视图并重定向它时,它停止工作了。要还原,我删除了那部分并还原了它,但它仍然没有用。
我该如何解决这个问题?我错过了什么吗?
A. 您应该将查看方法限制为您期望使用的实际方法 the require_http_methods decorator
from django.views.decorators.http import require_POST
@require_POST
def uploadFile(request):
file = request.FILES.get('img')
filename = file.name
key = 'media/' + filename
s3_resource = boto3.resource('s3')
# ....
return redirect('data:uploadStatus')
不使用 POST 调用此端点的方式将收到 405 Method not allowed 响应。更容易调试并弄清问题所在。
B. 确保您在前端的 Ajax 调用遵循重定向。
cache
参数对于 POST 不是必需的(除非您计划用于 IE8)
关于 contentType=false
和 processData=false
:在我看来,这仍然是一个常规的 multipart-formdata 电话。不要这样做,除非你知道你为什么这样做。您的 Django 代码看起来可以很好地处理常规表单数据,无需修改默认行为。
C. 你也必须实现一个错误回调:
}).done(function(data) {
}).fail(function(xhr, text, error) {
console.log(text, error)
});
我想发生的是一些您没有在 JS 代码中处理的错误。
您还没有添加您的设置,所以我不能确定,但我想您没有正确设置 AJAX 的 CSRF 配置。解决此问题的一种方法是将 CSRF cookie 也添加到 AJAX 请求中。 CSRF 表单字段和 cookie 都必须存在。