簡體   English   中英

Django 視圖在 Ajax 請求期間返回 None

[英]Django view returns None during Ajax request

我有一個 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')

調用這個后台任務 function 的視圖也應該重定向視圖,這將顯示上傳的狀態。

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.您應該使用require_http_methods 裝飾器將您的視圖方法限制為您期望的實際方法

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 調用遵循重定向。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM