Можно ли передать ответ Ajax в качестве переменной контекста шаблона в Django? - PullRequest
1 голос
/ 20 июня 2020

Я отправил Ajax запрос на сервер, чтобы получить отфильтрованные данные, и вот образец, который я получаю от сервера:

(3) [{…}, {…}, {…}]
0: {id: 1, title: "12 Rue Longueil", slug: "12-rue-longueil", latitude: null, longitude: null, …}
1: {id: 2, title: "15 Rue Sherbrooke LM", slug: "15-rue-sherbrooke-lm", latitude: null, longitude: null, …}
2: {id: 3, title: "Cycle Neron", slug: "cycle-neron", latitude: "-73.5987000000000000", longitude: "45.4799000000000000", …}
length: 3
__proto__: Array(0)

данные, указанные выше, регистрируются с консоли.

I хотите отображать эти данные в тегах HTMl на картах ниже.

enter image description here

but for that I need to use that received data and create children using JavaScript e.g. document.createElement('DIV'). and then place these data.

  $(document).on('submit', "#filterform", function (e) {

        e.preventDefault();

        $.ajax({
            type: 'GET',
            url: "{% url 'listing:search' %}",
            data: {
                listing_for: $('#listing_for').val(),
                // cutted
            },

            success: function (response) {
                const listings = eval(response);
    
                const content = document.getElementById('content');

                for (let i = 0; i < listings.length; i++) {
                    const div = document.createElement('div');
                    div.className = 'listing mgb-1';
                    div.innerHTML = data[i].title;
                    content.appendChild(div);

                    // have to create, add lots of divs and classes
                }

            }
        })
    })

I was wondering if there is a way to sent Ajax request data as template variable? Or do I have to hardcode all HTML tags using Javascript?

Edit: Edited content based on first answer creating a separate HTML.

def search(request):
    ...
    lst = list()

    for listing in queryset:
        ser = ListingSerializer(listing)
        lst.append(ser.data)
    
    return render(request, 'listing/newHtmlFile.html', {'listings': json.dumps(lst)})

separate HTML:

{% for list in listings %}
  {{list.title}}   {% endfor%}  

и ajax запрос:

success: function (response) {
    document.querySelector('#content').insertAdjacentHTML('beforeend', response);
}

Ответы [ 2 ]

1 голос
/ 20 июня 2020

Быстрый и, возможно, «грязный» способ сделать это - использовать строки обратных кавычек в javascript:

success: function (r) {
    const listings = JSON.parse(r);  // with the correct headers from django, this should't be needed.
    listings.forEach(e => $('#content').append(`
        <div class="listing mgb-1">${e.title}</div>
    `));
}

Вы должны вернуть свои данные из django с соответствующими заголовками, чтобы вы автоматически получите json и не должны eval(response).

1 голос
/ 20 июня 2020

Да, можно. По сути, идея состоит в том, чтобы создать отдельный файл HTML, который будет отображаться представлением, обрабатывающим запрос AJAX. Затем вы можете использовать JavaScript и функцию insertAdjacentHTML(), чтобы вставить его в исходный файл HTML.

Взгляните на этот пример:

view:

def ajax_handler(request):
    # ... logic
    return render(request, 'newHtmlFile.html', {'your_context': data})

Исходный HTML файл

<div id='container'>
    
</div>

newHtmlFile. html

<p>{{ your_context }}</p>

JavaScript часть ( в этом примере я использую Vanilla, а не JQuery)

let ajax = new XMLHttpRequest();
ajax.onreadystatechange = function(){
    if (this.readyState === 4){
        if (this.status === 200){
            document.querySelector('#container').insertAdjacentHTML('beforeend', this.responseText);
        }
    }
}
ajax.open('GET', '/ajax-handler-url', true);
ajax.send();

Если вам интересно узнать, как это работает, мы можем разбить его следующим образом:

  1. У вас есть некоторые данные (например, набор запросов, в вашем случае) в вашем представлении
  2. Вы вызываете метод render() и передаете эти данные в качестве данных контекста в шаблон
  3. Метод render() на самом деле делает (позвольте мне быть здесь лишним) визуализировать файл HTML (объединяя сам HTML с данными контекста, которые вы передали) и возвращайте объект HTTPResponse, содержащий визуализированный текст.
  4. Этот визуализированный текст (который представляет собой строку байтов, представляющую содержимое визуализированного HTML ) дается как ответ клиенту. В этом случае он передается специально функции $.ajax(), которая сделала запрос.
  5. Мы используем функцию insertAdjacentHTML(), чтобы добавить этот отображаемый текст к желаемому элементу (в приведенном выше примере #container div).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...