Как получить доступ к Ajax POST-запросу из Javascript в Django - PullRequest
0 голосов
/ 11 апреля 2019

Я отправляю запрос Ajax POST Django из модального Javascript. Маркер csrf включен правильно (после сильной головной боли ...), но по какой-то причине я не могу «извлечь» данные запроса в моем views.py. Я добавил несколько комментариев в код, чтобы указать, что, кажется, работает

Я читал все, что мог найти по этому вопросу, но все еще не мог найти ошибку, поэтому любые входные данные будут высоко оценены. Спасибо!

Javascript

function getMenuItem(id){
    console.log(id); // menuitem id prints correctly

    // Open request to get menuitem
    const request = new XMLHttpRequest();
    request.open('POST', '/menuitem');

    // Include csrf token in header so Django will accept the request
    const header =  "X-CSRFToken"
    const token = Cookies.get('csrftoken'); // Using the js-cookie library
    console.log(token); // token prints correctly
    request.setRequestHeader(header, token);

    // Send request
    request.send(id);

    //Once request is received parse it and insert result in DOM
    request.onload = () => {
        const received = request.responseText;
        console.log(received); // Prints the debug message from Django
        const parsed = JSON.parse(received);
        document.getElementById('menuItem').innerHTML = parsed;
    };
};

views.py

def menuitem(request):
    if request.method == 'POST':
        id = request.body # I have also tried HttpRequest.body  
        print(id) # Does not print 
        menuitem = MenuConfiguration.objects.filter(id=id).all()
        menuitem = serializers.serialize('json', menuitem)
        menuitem = json.loads(menuitem)

        return menuitem

Traceback

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/utils/deprecation.py", line 93, in __call__
    response = self.process_response(request, response)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/middleware/clickjacking.py", line 26, in process_response
    if response.get('X-Frame-Options') is not None:
AttributeError: 'list' object has no attribute 'get'
[11/Apr/2019 06:10:18] "POST /menuitem HTTP/1.1" 500 54835

Ответы [ 2 ]

0 голосов
/ 12 апреля 2019

Я сделал так, чтобы он работал с приведенными ниже настройками, поэтому теперь запрос отправляется правильно и обрабатывается Django, а результат запроса принимается JS. Мне пришлось немного взломать, чтобы удалить [] из текстового объекта ответа, чтобы JSON.parse мог его обработать.

Хотя у меня есть новая проблема: получение значений внешних ключей, включенных в запрос (т. е. не только ключей, как это происходит сейчас). Я опубликую отдельный вопрос по этому поводу, но, пожалуйста, оставьте комментарий, если у вас есть решение для этого с манжеты

Javascript

function getMenuItem(id){
    console.log(id);

    // Open request to get menuitem
    const request = new XMLHttpRequest();
    request.open('POST', '/menuitem');

    // Include csrf token in header so Django will accept the request
    const header =  "X-CSRFToken";
    const token = Cookies.get('csrftoken'); //Using the js-cookies library
    request.setRequestHeader(header, token);

    // Formdata object to structure data as if submitted from a form
    const data = new FormData();
    data.append('id', id);

    // Send request
    request.send(data);

    console.log("Request sent");

    //Once request is received parse it and insert result in DOM
    request.onload = () => {
        const received = request.responseText;
        console.log("Data as received:  " + received);

        // Remove [] from response text
        removedfirst = received.substring(1);
        removedlast = removedfirst.substring(0, removedfirst.length-1);
        console.log("Data with [] removed: " + removedlast);

        // Parse to JS object
        const parsed = JSON.parse(received);
        console.log("Output of JSON.parse:");
        console.log(parsed);

        // Insert value into DOM
        document.getElementById('outputField').innerHTML = parsed[0].fields.base;
    };
};  

views.py

def menuitem(request):
    if request.method == 'POST':
        # Get product id from request
        id = request.POST.get('id')

        # Retrieve data for specific product id
        menuitem = MenuConfiguration.objects.filter(id=id).all()

        # Turn query response into JSON 
        data = serializers.serialize('json', menuitem)

        # Return a HttpResponse containing the JSON data
        return HttpResponse(data, content_type='application/json')

Вывод с консоли JS:

журналы консоли

0 голосов
/ 11 апреля 2019

Здесь есть несколько вещей, к которым нужно обратиться.

В вашем коде Javascript вы должны отправить значение id, правильно закодированное как параметр формы, используя синтаксис key=val:

request.send("id=" + id);

Тогдапо вашему мнению, вы должны извлечь значение из словаря POST:

if request.method == 'POST':
    id = POST['id']  # Retrieve the value of the id parameter

Наконец, ваше представление должно вернуть HttpResponse.Поскольку вы хотите вернуть JSON, вы должны передать это в HttpResponse и установить аргумент content_type в application/json:

if request.method == 'POST':
    id = POST['id']
    menuitem = MenuConfiguration.objects.filter(id=id).all()
    data = serializers.serialize('json', menuitem)

    # Return a HttpResponse containing the JSON data
    return HttpResponse(data, content_type='application/json')  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...