Django视图在Ajax请求期间返回None

问题描述

我有一个Django Web应用程序,我正在尝试通过ajax调用来上传大图像。如果可以上传要上传的图像,则将使用pythonocc库读取该图像并返回卷信息。由于此过程需要很长时间,因此我尝试使用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方法不允许”响应。调试和弄清楚出了什么问题更容易。

B。。请确保您在前端的Ajax调用遵循重定向。

POST不需要cache参数(除非您计划使用IE8)

关于contentType=falseprocessData=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都必须存在。

请参见https://docs.djangoproject.com/en/3.1/ref/csrf/#ajax

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...