Django + AJAX

7 хв. читання

Привіт всім Кодегідерам!

У коментарях до статті про розробку першого додатку на Django користувач x_pal надихнув мене на написання статті про те, як додати AJAX-запити в Django додаток.


Запити в інтернеті

Теорія(для тих, хто взагалі новачок у вебі).

Запит відправляється браузером на сервер, коли користувач запитує відкрити якусь сторінку, ввівши URL адресу в рядок браузера, або перейшовши по лінку.

Щоб краще зрозуміти, пропоную поглянути на логи вбудованого в Django dev сервера. Я запустив сервер і відкрив у браузері головну сторінку мого додатку:

[31/Jul/2016 17:09:16] "GET / HTTP/1.1" 200 15664
[31/Jul/2016 17:09:17] "GET /static/style.css HTTP/1.1" 200 166
[31/Jul/2016 17:09:17] "GET /static/img/logo.png HTTP/1.1" 200 8192
[31/Jul/2016 17:09:18] "GET /static/img/one-more-image.png HTTP/1.1" 200 30170
[31/Jul/2016 17:09:17] "GET /static/script.js HTTP/1.1" 200 17483
...

Тобто, щоб браузеру відобразити головну сторінку мого сайту, він посилає приблизно такого типу інформацію (GET / HTTP/1.1) на сервер. І от на сервері розробнику треба написати код який би обробляв запит, розбирав, що браузер власне хоче і надсилав відповідь браузеру - результат виконання: (200) - код, що означає ОК, та тіло відповіді - готову html сторінку. Крім того, треба ще отримати файли CSS стилів, JS скриптів та зображенm. Як це відбувається? Браузер запитав головну сторінку: [31/Jul/2016 17:09:16] "GET / HTTP/1.1" 200 15664, сервер надіслав йому її, далі браузер починає цю сторінку обробляти, натикається на CSS файл, який знаходиться за адресою /static/style.css і знову посилає запит на сервер, просячи ще й і CSS файл і так далі...

Типи запитів

Весь інтернет працює на запитах GET, POST(найчастіше використовуються), PUT, DELETE і ще декількох. Але ми зупинимось на перших двох, про решту ви можете почитати в інтернеті самостійно, зараз це не головне.

  • GET - в основному, запит певноъ інформації: сторінки повністю (з прикладу Django сервера - [31/Jul/2016 17:09:16] "GET / HTTP/1.1" 200 15664) або окремого файлу ([31/Jul/2016 17:09:17] "GET /static/style.css HTTP/1.1" 200 166). Простіше, це те що ми бачимо в адресному рядку, коли відкриваємо будь-який сайт.

  • POST - використовується для передачі даних, які користувач залишив у формі (знову ж таки з Django сервера [31/Jul/2016 17:42:16] "POST /login/ HTTP/1.1" 200 180). Його не видно в браузерному рядку і він є краще захищеним, ніж GET.


І нарешті, AJAX

AJAX - це технологія, що дозволяє додати текст, зображення, css файл, все що завгодно, на сторінку, або надіслати дані з форми на сторінці, при цьому не перезавантажуючи її. Круто, чи не так? Як це робиться? Просто: розробник пише певний js код, який надсилає такий самісінький запит, як і браузер, коли йому треба відкрити сторінку якогось сайту.

Тобто все, що вам треба, це кілька рядків JS коду, щоб надіслати запит і Django view (не завжди), щоб запит обробити. Тож вам майже не потрібно ніяких нових знань в Django, щоб додати AJAX.

Тепер на прикладі:

Зробимо простеньку кнопку яка б показувала, ще якусь інформацію на сторінці. Тобто натиснувши на кнопку, кристувачеві має з'явитись ще трохи тексту.

HTML:

<a href="#" id="ajax-text-me">Натисни мене ніжно</a>
<div id="more-text-here1"></div>
<div id="more-text-here2"></div>

Просте посилання і 2 контейнери в які будемо поміщати текст.

JS код:

<script type="text/javascript">
	$(document).ready(function () {
		$("#ajax-text-me").click(function() {
			$.ajax({
				type: 'GET',
				async: true,
				url: '/ajax/',
				data: "param1=value1&param2=value2;",
				success: function(data) {
					$("#more-text-here1").append(data['first-text']);
					$("#more-text-here2").append(data['second-text']);

				},
				dataType: 'json',
			});
		});
	});
</script>

Отож, вся магія в jquery методі $.ajax. Саме цей метод і буде надсилати запит на сервер. Параметр type - тип запиту (GET, POST ...), async - чи можна асихронно далі виконувати js код, навіть якщо ще не прийшла відповідь від сервера, url - url куди посилаємо запит, data - необов'язкові параметри запиту, точно так само, як в GET, і success - що відбуватиметься, якщо прийде відповідь від сервера.

Детальніше про параметри в методі AJAX можете почитати в цій статті тут же на Codeguida. Тепер серверна сторона, Django:

#urls.py
url(r'^ajax/$', views.add_ajax),

#views.py
from django.http import Http404, JsonResponse


def add_ajax(request):
    if request.is_ajax():
        response = {'first-text': 'Lorem Ipsum is simply dummy text', 'second-text': 'to make a type specimen book. It has '}

        return JsonResponse(response)
    else:
        raise Http404

Тут все як і завжди, тільки варто перевіряти чи запит AJAX, метод is_ajax(), в змінну response записуємо наші дані, пакуємо все в JSON, і віддаємо браузеру. От і все.


Тепер ще кілька корисних штук

Щоб додати на сторінку не тільки текст, але й HTML, і плюс прорендерити його, як звично в Django:

from django.template.loader import render_to_string

...

context = {
    'par1': val1,
}
rendered = render_to_string('templates/some-tpl.html', context)
response = {'html': rendered}

...

Просто спершу рендеримо шаблон зі змінними, а потім, знову ж таки, пакуємо в JSON і повертаємо.


Сабміт форм AJAX

$.ajax({
    url: "/add_book/",
    type: "POST",
    data: $('#form').serialize();
    success: function(data) {
        if (data['result'] == 'success') {
            console.log('ok');
            $("#form .result").append(data['response']);
        }
        else if (data['result'] == 'error') {
            console.log('error');
            $("#form .error").append(data['response']);
        }
    },
});

Загалом, тут все теж саме... Тільки type - POST і data - передаються дані, які отримуються з форми за допомогою методу serialize(). І далі відображаємо результат.

def form_handle(request):
    if request.method == 'POST' and request.is_ajax():
        form = Form(request.POST)
        response, context = {}, {}
        if form.is_valid():
            record = form.save()
            rendered = render_to_string('form-result.html', {'record': record}) #якщо треба відображати якісь результати (напр. коментарі)
            context = {'response': rendered, 'result': 'success'}
        else:
            for error in form.errors:
                response[k] = form.errors[error][0]
                context = {'response': response, 'result': 'error'}
        return JsonResponse(context)
    else:
        raise Http404

Все як завжди...

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.8K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація