
Працюючи з веб-проектами в Django інколи виникає потреба зобразити певні елементи сторінки після її завантаження, тобто асинхронно, методом AJAX.
Таким чином користувач не чекає обрахунку усіх даних (дивлячись на порожню, або напівзавантажену сторінку), а відразу бачить основну інформацію, яка згодом оновлюється.
Існують спеціальні додатки що реалізовують ці функції в Django (наприклад Dajax). Але мені видалося простішим реалізовувати їх через старий добрий javascript-фреймворк jQuery.
Мало який веб-проект обходиться зараз без jQuery. Але навіть якщо його раніше не було, це вартує уваги, завдяки своїй простоті.
Ajax в Django через jQuery
html:
<!-- Елемент що активує процес -->
<a id="test" href="javascript:">Натисни мене ніжно</a>
<!-- Елемент, текст якого буде змінено -->
<div id="target">Я готовий до змін.</div>
В заголовках чи підвалі html:
<!-- Підключаємо jQuery -->
<script src="/js/jquery-1.8.2.min.js"></script>
<script type="text/javascript">
// Магія розпочнеться лише після повного завантаження сторінки
$(document).ready(function () {
// Посилання з id="test" буде тригером події
$("#test").click(function() {
// AJAX-запит на потрібну адресу
$.get("/ajax_test/", function(data) {
// Замінюємо текст тегу з id="target" на отримані дані
$("#target").html(data.param1+' '+data.param2);
});
});
});
</script>
urls.py:
urlpatterns = patterns('',
(r'^ajax_test/$', ajax_test),
)
views.py:
from django.utils import simplejson
def ajax_test(request):
results = {'success':False}
# Тут — потрібні нам алгоритми
if True:
results = {'success':True, 'param1':'Ти таки', 'param2':'натиснув його!'}
json = simplejson.dumps(results)
return HttpResponse(json, mimetype='application/json')
Логіка роботи:
- В коді є посилання
aз ідентифікаторомtest - На це посилання, завдяки jQuery, чіпляється подія
click(натиснення посилання) - Якщо здійснюється натиснення, то відбувається AJAX-запит адреси "/ajax_test/"
- /ajax_test/ прописано в урлах Django, тому виконується функція
ajax_test - Функція готує дані та повертає їх у вигляді списку python
- Список конвертується у формат JSON та повертає дані "сторінці"
- "Сторінка" отримує дані у вигляді змінної
data - jQuery замінює код тегу
divна отримані дані
Django-функція може повертати не лише JSON, але і XML, HTML тощо. Треба пам’ятати про правильний mimetype.
Також, django-функція може отримувати "на вхід" POST- чи GET- дані, які стандартними засобами можна перевіряти і отримувати всередині функції.
Шаблон Django як AJAX-відповідь
Цікаво і дуже корисно, що у відповідь на AJAX-запит можна повертати код, сформований шаблоном Django:
def ajax_test(request):
object = ...
return render_to_response('ajax_response.html', { 'object': object })
Це дозволяє повертати у відповідь на AJAX-запит не лише елементарні дані, а цілі сторінки, таблиці тощо.
AJAX-запит для певних елементів, з використанням атрибутів
Є задача: зобразити на сайті список об’єктів і асинхронно опитати їх параметри. В моєму випадку це були якісь модеми і скажімо пінг до них.
Для jQuery це не є проблемою:
<dl>
<dd class="modem_levels" modem_name="152"></dd>
<dd class="modem_levels" modem_name="153"></dd>
<dd class="modem_levels" modem_name="154"></dd>
</dl>
<script type="text/javascript">
$(document).ready(function () {
// Пробігтися по усіх елементах dd з id="modem_levels"
$('dd.modem_levels').each(function() {
var dom_element = $(this);
// Отримати номер модему використовуючи власний атрибут
var modem_id = dom_element.attr("modem_name");
// Здійснити AJAX-запит підставляючи в адресу номер модему
$.get("/ajax/modem/"+modem_id+"/levels/", function(data) {
// Відобразити результат
dom_element.html(data);
});
});
});
</script>
Не навантажуючи HTML-код зайвими функціями, для кожного елементу, jQuery саме знайшло їх, отримало потрібні атрибути і вписало відповідні дані, отримані по-AJAX.
Звичайно це дуже прості приклади. Я не зачіпав питання перевірки даних, особливостей формування різних типів відповідей. В основному тому, що сам їх ще не розумію. ;)
Але завдяки jQuery, AJAX в Django не видається таким страшним, як здавалося.