Представление Django не получает ajax-запрос

#python #django #ajax #web-deployment

#python #django #ajax #веб-развертывание

Вопрос:

В моем шаблоне есть скрипт, который пытается отправить данные в представление django во время события onbuttonclick. Моя проблема в том, что запрос, похоже, не попадает в представление. Консоль браузера видит запрос правильно и все, но представление django даже не возвращает true, когда я вызываю request.is_ajax() .

request.method возвращает GET вместо POST, а данные пусты. Это поведение является постоянным независимо от типа запроса.

HTML

 <a onclick="setGetParameter(this)" pid="some_id">Some Text</a>
 

.js

 <script>
  var csrftoken = Cookies.get('csrftoken');

  function setGetParameter(el){

      var stuff = $(el).attr('pid');

      $.ajax({
        type: 'POST',
        headers: { "X-CSRFToken": csrftoken },
        url: '/view_url/',        
        data: {'datatopass': stuff},
        success: function(response){
          alert(response);
        }
      });
  }
  </script>
 

urls.py

 path('view_url/', views.test),
path('', views.home),
 

views.py

 def test(request): 
    output = request.is_ajax()
    return HttpResponse(output)
 

Ответ №1:

В Django 3.1 is_ajax() метод устарел. См. раздел Разное Django 3.1

Итак, для Django > = 3.1 вы можете сделать это так:

 if request.headers.get('x-requested-with') == 'XMLHttpRequest':
    is_ajax = True
else:
    is_ajax = False
 

И убедитесь, что в заголовках запросов AJAX добавлена следующая строка:

 "X-Requested-With": "XMLHttpRequest"
 

Я бы использовал click метод jQuery:

 <a pid="some_id">Some Text</a>

<script>
var csrftoken = Cookies.get('csrftoken');

function setGetParameter(el){

    var stuff = $(el).attr('pid');

    $.ajax({
        type: 'POST',
        headers: { "X-CSRFToken": csrftoken },
        url: '/view_url/',        
        data: {'datatopass': stuff},
        success: function(response){
            alert(response);
        }
    });
}

$(document).ready(function(){
    $('a[pid]').click(function(){
        setGetParameter(this);
    });
});
</script>
 

Также я бы использовал объекты JsonResponse:

 from django.http import JsonResponse

def test(request): 
    output = request.is_ajax()
    return JsonResponse({'is_ajax': output})
 

Для сериализации объектов, отличных dict от того, который вы должны установить safe для параметра False :

 response = JsonResponse([1, 2, 3], safe=False)
 

Комментарии:

1. не сработало. {«is_ajax»: false} — это то, что я получаю.

2. @KingDavid, а если вы добавите это: "X-Requested-With": "XMLHttpRequest" в заголовки?

3. Проблема заключается не только в получении флага is_ajax, запрос, похоже, не попадает в представление. request.method возвращает GET, даже если тип запроса POST . Нет данных ни в request.body, ни в request.POST.get(‘datatopass’); независимо от используемого метода. Я использовал request.is_ajax() просто чтобы убедиться, что я получаю запрос, но моя проблема в том, что я так не думаю. Все еще не работает с дополнительным заголовком, который вы предложили.

4. @KingDavid, что происходит, когда вы вызываете AJAX из консоли браузера?

5. Как бы мне это сделать?

Ответ №2:

После нескольких дней биения головой о стену я решил использовать другую реализацию. Похоже, я могу отображать данные только на странице, которая изначально отправила запрос.