Цель лекции: рассмотреть основы технологии AJAX, познакомиться с понятием формы, рассмотреть основные типы виджетов, создать страницу поиска твитов, познакомиться с методами jQuery, добавить автодополнение хэштегов при отправке твита.
Ключевые термины: AJAX, CSS, HTML, jQuery, форма, фреймворк, твит, хештег, имплементация, элемент, запрос, поиск, метод, атрибут, приложение.
Появление AJAX стало важной вехой в истории Веб 2.0. AJAX — это группа технологий, что позволяет разработчикам создавать интерактивные, с большими возможностями веб-приложения. Большинство из этих технологий были доступны за многие годы до появления самого AJAX. Однако появление AJAX представляет переход Web от статических страниц, которые необходимо обновлять всякий раз, когда происходил обмен данными к динамическим, гибким и интерактивным пользовательским интерфейсам.
Так как наш проект является приложением Веб 2.0, оно должно быть более нацелено на пользователей. Успех нашего приложения зависит от получения пользователем возможности размещать и обмениваться контентом на нем. Таким образом, пользовательский интерфейс нашего приложения является одной из наших основных проблем. Эта лекция улучшит интерфейс нашего приложения с помощью описания возможностей AJAX, что сделает его более удобным для пользователей и интерактивным.
AJAX, которая расшифовывается как Asynchronous JavaScript and XML (Асинхронный JavaScript и XML), состоит из следующих технологий:
Иногда используется XML, но это может быть в HTML, обычном тексте или формате на основе JavaScript, называемом JSON.
AJAX технологии позволяют кодировать обмен данными на клиентской стороне с сервером за кулисами, без перезагрузки всей страницы каждый раз, когда пользователь делает запрос. С помощью AJAX, веб-разработчик может увеличить интерактивность и удобство использования ' веб-страниц.
AJAX обеспечивает следующие преимущества при имплементации в правильных местах:
Существует множество примеров веб-приложений, использующих AJAX: карты Google и Gmail, возможно, два наиболее известных примера. В самом деле, эти два приложения играют важную роль в распространении использования AJAX из-за того успеха, которыми они пользуются. Что отличает Gmail от других почтовых сервисов, это его пользовательский интерфейс, который позволяет пользователям интерактивно управлять электронной почтой, не дожидаясь перезагрузки страницы после каждого действия, и это создает лучший пользовательский опыт и позволяет Gmail чувствовать себя отзывчивым и многофункциональным приложением, нежели простой веб-сайт.
В этой лекции объясняется, как использовать AJAX с Django, с тем чтобы сделать приложения более гибким и удобным для пользователей. Мы имплементируем три наиболее распространенных функции AJAX, которые могут быть сегодня найдены в веб-приложениях. Однако, прежде, мы узнаем о преимуществах использования инфраструктуры AJAX, в отличие от работы с raw JavaScript функциями.
Так как мы уже использовали bootstrap в нашем проекте, нам не нужно настраивать его отдельно для AJAX и jQuery.
Есть много преимуществ использования AJAX фреймворка:
Без инфраструктуры AJAX разработчики должны отслеживать поддержку браузера для возможностей JavaScript, которые они используют и должны работать вокруг ограничений, которые присутствуют в некоторых браузерах для выполнения JavaScript.
С другой стороны, при использовании фреймворка AJAX, фреймворк заботится об этом для нас; он абстрагирует доступ к имплементации JavaScript и сделок с шин различия и особенности JavaScript в браузерах. Банки металлические способом, мы можем сосредоточиться на разработке функции вместо тревожиться о браузере различия и ограничения.
Поэтому даже если вы не решитесь использовать инфраструктуру AJAX, вы найдете для себя написание библиотеки функций, которая инкапсулирует JavaScript зал и делает их более удобными. Однако, зачем изобретать велосипед, когда много отличных библиотек open source уже доступно?
AJAX фреймворки, имеющихся на рынке сегодня варьируются от всеобъемлющих решений, которые предоставляют серверные и клиентские компоненты до легких клиентских библиотек, которые упрощают работу с JavaScript. Учитывая, что мы уже используем Django на серверной стороне, мы хотим фреймворк только с клиентской стороны. В дополнение к этому фреймворк должны быть легко интегрируем с Django без требования любых дополнительных зависимостей. Наконец, желательно, выбрать легкий и быстрый фреймворк. Есть множество отличных фреймворков, которые отвечают нашим требованиям, таких как Prototype, Yahoo! UI Library, и jQuery.
Однако для нашего приложения, я собираюсь выбрать jQuery, потому что это самый легкий фреймворк из трех. Он также весьма активно развивается сообществом и имеет широкий спектр плагинов. Если у вас уже есть опыт с другим фреймворком, вы можете продолжить использовать его во время этой главы. Правда, вам придется адаптировать JavaScript код в этой главе под ваш фреймворк, но код Django на стороне сервера останется таким же, независимо от того, какой фреймворк вы выберете.
Вам нужно также импортировать bootstrap и jQuery.Таким образом, не нужно никакой особой установки или импорта для использования функций AJAX в нашем проекте Django.
Прежде чем мы начнем имплементировать улучшения AJAX в наш проект, давайте пройдем через краткое введение в основы jQuery.
jQuery — это библиотека функций JavaScript, которая облегчает взаимодействие с HTML-документами и управляет им. Библиотека предназначена для сокращения времени и усилий на написание кода и достижения совместимости между браузерами, и в то же время она в полной мере использует то, что JavaScript предлагает для создания гибких и интерактивных веб-приложений.
Рабочий процесс с помощью jQuery в общем состоит из следующих двух этапов:
jQuery предоставляет простой подход для выбора элементов: она работает путем передачи строки селектора CSS в функцию $ (). Ниже приведены некоторые примеры, которые иллюстрируют использование этой функции :
Функция $ () создает и возвращает объект jQuery.После этого можно вызывать методы этого объекта для взаимодействия с выбранным HTML-элементом.
jQuery предлагает разнообразные методы для обработки HTML документов. Вы можете скрыть или показать элементы, присоединить обработчики событий к событиям, изменять свойства CSS, манипулировать структурой страницы и, самое главное, формировать AJAX-запросы.
Для отладки, мы выберем браузер Internet Explorer как браузер нашего выбора. Internet Explorer является одним из самых передовых JavaScript отладчиком в виде его инструментов разработчика Django. Чтобы запустить его, нажмите на клавиатуре Ctrl + Shift + J.
Поэкспериментируем с методами, изложенными в этом разделе, запустим сервер разработки и перейдем на страницу профиля пользователя (http: //127.0.0.1:8000/user/test/). Откройте консоль инструментов(нажав на клавиатуре Ctrl + Shift + J) разработчика и нажмите F12, попробуйте выбрать элементов и манипулировать ими.
Скрытие и отображение элементов
Давайте начнем с чего-то простого. Чтобы скрыть элемент на странице, вызовите метод — hide() на нем.Чтобы показать его снова, вызовите метод show(). Например попробуйте это с меню навигации, называемом navbar в загрузчик приложения:
>>> $(".navbar").hide()
>>> $(".navbar").show()
Также можно анимировать элемент во время скрытия и показа его. Попробуйте fadeOut(), fadeln(), slideUp() или slideDown () — методы, чтобы увидеть два из этих анимационных эффекта.
Конечно эти методы (как и все другие методы jQuery) также работают, если вы выберете более одного элемента за один раз. Например, если открыть профиль пользователя и ввести следующий вызов метода в консоли средства разработчика, все твиты исчезнут:
>>> $(".well").slideUp()
Далее мы узнаем, как изменить свойства CSS элементов. jQuery предлагает метод, называемый css() для выполнения CSS операций. Если вызвать этот метод с именем свойства CSS, переданным в виде строки, она возвращает значение этого свойства:
>>> $(".navbar").css("display")
Результатом этого является следующее:
block
Если второй аргумент передается в этот метод, он задает указанное свойство CSS выбранного элемента для дополнительного аргумента:
>>> $(".navbar").css("font-size", "0.8pt")
Результатом этого является следующее сообщение:
<div id="nav" style="font-size: 0.8em;"></div>
В самом деле вы можете манипулировать любой атрибут м HTML и не только свойствами CSS. Чтобы сделать это, используйте метод attr(), который работает аналогично методу css(). Вызвав его по имени атрибута, он возвращает значение атрибута, в то время как его вызов с именем атрибута или пары значений задает атрибуту переданное значение:
>>> $("input").attr ("size", "48")
Это приводит к следующему:
<input id="idcountry" name="country" type="hidden" value="Global" size="48"> <input type="submit" value="post" size="48">
Это одновременно изменит размер всех входных элементов на 48.
В дополнение к этому, есть методы ярлыка, чтобы получать и устанавливать часто используемые атрибуты, такие как val(), который возвращает значение поля ввода, когда вызывается без аргументов и задает значение для аргумента, если вы передадите аргумент. Существует также метод html() для контроля HTML кода внутри элемента.
Наконец, существует два метода, которые могут использоваться для присоединения или отсоединения CSS класса для элемента: это методы addClass() и removeClass(). Третий метод служит для переключения CSS класса и он называется методом toggleClass (). Все эти методы класса принимают имя класса, который необходимо изменить как параметр.
Теперь, когда вам удобно манипулировать HTML-элементами, давайте посмотрим, как добавлять новые элементы или удалить существующие элементы. Чтобы вставить HTML-код перед элементом, используйте метод before(), а для вставки кода после элемента, используйте метод after().Обратите внимание, как методы jQuery хорошо именованы и их очень легко запомнить!
Давайте протестируем эти методы, вставив скобки вокруг списков тегов на странице пользователя. Откройте вашу пользовательскую страницу и введите следующее в консоли средств разработчика:
>>> $(".well span").before ("<strong>(</strong>")
>>> $(".well span").after ("<strong>)</strong>")
Вы можете передать любую строку, какую вы хотите, с методами before() или after(). Строка может содержать обычный текст, один или больше элементов HTML. Эти методы предоставляют очень гибкий способ для динамического добавления элементов HTML в документ HTML.
Если вы хотите удалить элемент, используйте метод remove(). Например:
$("#navbar").remove()
Этот метод не только скрывает элемент, он также удаляет его полностью из дерева документов. Если вы попытаетесь выбрать элемент снова, после использования метода remove (), вы получите пустой набор:
>>> $("#nav")
Результатом этого является следующим:
[]
Конечно, это только удаляет элементы из текущего экземпляра страницы. Если вы обновите страницу, элементы появятся снова.
Хотя CSS селекторы предоставляют очень мощный способ для выбора элементов, бывают случаи, когда вы можете захотеть обойти дерево документа, начиная от конкретного элемента.
Для этого jQuery предоставляет несколько методов. Метод parent () возвращает родителя текущего выбранного элемента. Метод children () возвращает всех непосредственных дочерних элементов выбранного элемента. Наконец, метод find () возвращает всех потомков текущего выбранного элемента. Все эти методы принимают необязательную строку CSS селектора для ограничения элементов теми, которые соответствуют результату селектора. Например, $(".column").find("span") возвращает всех потомков <span> столбца aclass.
Если вы хотите получить доступ к отдельному элементу группы, используйте метод get (), который принимает индекс элемента в качестве параметра. Метод $("span").get(0), например, возвращает первый элемент <span> из выбранной группы.
Далее мы изучим обработчики событий. Обработчик событий — это функция JavaScript, которая вызывается, когда происходит определенное событие, например, при нажатии кнопки или отправке формы. jQuery предоставляет большой набор методов для присоединения обработчиков к событиям; события, представляющие особый интерес в нашем приложении - щелчки мышью и отправка формы. Для обработки события нажатия на элемент, мы выбираем этот элемент и вызываем метод click(). Этот метод принимает в качестве параметра функцию обработчика событий. Давайте попробуем это в нашей консоли разработчика.
Откройте страницу профиля пользователя приложения и вставьте кнопку после твита:
>>> $(".well span").after("cbutton id=\"test-button\">Нажми!</ button>")
Обратите внимание, что нам пришлось опустить кавычки в строках переданных методу after().
Если вы попытаетесь нажать кнопку, ничего не произойдет, так что давайте присоединим обработчик событий к нему:
>>> $("#test-button").click(function () { alert("Вы меня нажали!"); })
Теперь, когда вы нажмете на кнопку,появится окно сообщения.Как это работает?
Аргумент, который мы передали в методе click(), может выглядеть немного сложным, так что давайте рассмотрим его снова:
function () { alert("Вы меня нажали!"); }
Кажется, что это должно быть объявлением функции, но без имени функции. Действительно эта конструкция создает так называемую анонимную функцию в терминологии JavaScript, и она используется, когда вам нужно создать функцию на лету и передать ее в качестве аргумента другой функции. Мы могли бы избежать с помощью анонимных функций и объявить обработчик события как обычную функцию
>>> function handler{ alertC("Вы нажали меня!"); }
>>> $("#test-button").click(handler)
Предыдущий код достигает того же эффекта, но первый является более кратким и компактным. Я настоятельно рекомендую вам привыкнуть к анонимным функциям в JavaScript (если вы еще не привыкли), как я уверен, что вы оцените эту конструкцию и найдете ее более удобной для чтения после использования его некоторое время.
Обработка формы отправки очень похоже на обработку щелчков мыши. Сначала выберите форму, затем вызовите метод отправки на нее, и затем передайте обработчик в качестве аргумента. Мы будем использовать этот метод несколько раз во время добавления функций AJAX к нашему проекту в последующих разделах.
Прежде чем мы закончим этот раздел, давайте поговорим о AJAX-запросах. jQuery предоставляет много способов, чтобы отправлять запросы AJAX на сервер. Существует, например, метод load(), который принимает URL-адрес и загружает страницу по URL-адресу в выбранный элемент. Существуют также методы для отправки запросов GET или POST и получения результатов. Мы изучим эти методы более подробно при имплементации функций AJAX в наш проект.
Мы будем постепенно вводить AJAX в наше приложение путем реализации живого поиска. Идея эта функции проста: когда пользователь вводит несколько ключевых слов в текстовое поле и нажимает на поиск, за кулисами срабатывает сценарий, чтобы получить результаты поиска и представить их на той же странице. Страница поиска не перезагружается, таким образом экономя пропускную способность и обеспечивая лучший и более отзывчивый опыт пользователя.
Прежде чем мы постепенно это реализуем, нам нужно иметь в виду одно важное правило работы с AJAX: напишите приложение, так чтобы оно работало без AJAX и затем предоставьте к нему AJAX. Если вы сделаете это, вы убедитесь, что каждый будет иметь возможность использовать ваше приложение, включая пользователей, которые не имеют JavaScript, а также включая и тех, кто используют браузеры без поддержки AJAX.
Так что прежде чем мы поработаем с AJAX давайте напишите простое представление, чтобы искать по названию закладки. Во-первых нам нужно создать форму поиска, поэтому откройте файл tweets/forms.py и добавьте в него следующий класс:
Сlass SearchForm(forms.Form):
query = forms.CharField(label='Enter a keyword to search for',
widget=forms.TextInput(attrs={'size': 32, 'class':'form-control search-query'}))
Как вы можете видеть, это довольно простой класс формы с только одним текстовым полем. Это поле будет использоваться пользователем для ввода ключевых слов поиска. Далее создадим представление для проведения поиска. Откройте файл tweets/views.py и введите следующий код в него:
class Search(View):
"""Search all tweets with query /search/?query=<query> URL"""
def get(self, request):
form = SearchForm()
params = dict()
params["search"] = form
return render(request, 'search.html', params)
def post(self, request):
form = SearchForm(request.POST)
if form.is_valid():
query = form.cleaned_data['query']
tweets = Tweet.objects.filter(text__icontains=query)
context = Context({"query": query, "tweets": tweets})
return_str = render_to_string('partials/_tweet_search.html', context)
return HttpResponse(json.dumps(return_str), content_type="application/json")
else:
HttpResponseRedirect("/search")
Помимо нескольких вызовов метода представление должно быть очень легко для понимания.
Если вы посмотрите на запрос GET, здесь все довольно просто, он подготавливает форму поиска и затем отображает ее.
Метод post() является тем методом где происходит волшебство. Когда мы отображаем результаты поиска, это просто макета отображения с формой поиска, так что если вы взглянете на новый файл, который мы создали, под названием search.html, вы можете увидеть следующее:
{% extends "base.html" %}
{% load staticfiles %}
{% block content %}
<div class="row clearfix">
<div class="col-md-6 col-md-offset-3 column">
<form id="search-form" action="" method="post">{% csrf_token %}
<div class="input-group input-group-sm">
{{ search.query.errors }}
{{ search.query }}
<span class="input-group-btn">
<button class="btn btn-search" type="submit">search</button>
</span>
</div><!-- /input-group -->
</form>
</div>
<div class="col-md-12 column tweets">
</div>
</div>
{% endblock %}
{% block js %}
<script src="{% static 'js/search.js' %}"></script>
{% endblock %}
Если вы посмотрите внимательно, вы увидите, что мы включили новый раздел раздела с именем {% block js %}. Концепция, используемая здесь, является такой же, как и {% block content %}, то есть, то что объявляется здесь, будет передаваться в файл base.html. Взяв это на заметку, посмотрим на измененный файл base.html. Мы увидим следующее:
{% load staticfiles %}
<html>
<head>
<link href="{% static 'css/bootstrap.min.css' %}"
rel="stylesheet" media="screen">
{% block css %}
{% endblock %}
</head>
<body>
<nav class="navbar navbar-default" role="navigation">
<a class="navbar-brand" href="#">MyTweets</a>
{% block navbar %}
{% endblock %}
</nav>
<div class="container">
{% block content %}
{% endblock %}
</div>
<nav class="navbar navbar-default navbar-fixed-bottom" role="navigation">
<p class="navbar-text navbar-right">Footer </p>
</nav>
<script src="{% static 'js/jquery-2.1.1.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<script src="{% static 'js/base.js' %}"></script>
{% block js %}
{% endblock %}
</body>
</html>
Предыдущий код ясно показывает два новых блока содержимого, а именно:
{% block css %}
{% endblock %}
{% block js %}
{% endblock %}
Они используются для включения типов соответствующих файлов и для отображения типы файлов с основы, так что поддержка проекта становится намного проще с помощью простого правила объявлять только один файл CSS и JavaScript на странице. Мы осуществим это позже в книге с концепцией, называемой assets pipeline.
Теперь, возвращаясь к нашей функции поиска AJAX, вы увидите, что этот файл search.html, аналогичен файлу tweet.html.
Для функции поиска мы создадим новый URL-адрес, который нам нужно добавить к файлу urls.py следующим образом:
url(r'^search/$', Search.as_view())
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from tweet.views import Index, Profile, PostTweet, HashTagCloud, Search
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', Index.as_view()),
url(r'^user/(\w+)/$', Profile.as_view()),
url(r'^admin/', include(admin.site.urls)),
url(r'^user/(\w+)/post/$', PostTweet.as_view()),
url(r'^hashTag/(\w+)/$', HashTagCloud.as_view()),
url(r'^search/$', Search.as_view()),
)
В файле search.html мы определили метод search.js; давайте создадим этот файл Javascript, чтобы действительно выполнялся запрос AJAX
$('#search-form').submit(function(e){
$.post('/search/', $(this).serialize(), function(data){
$('.tweets').html(data);
});
e.preventDefault();
});
Этот код JavaScript срабатывает при отправке формы, это формирует AJAX запрос post к /search пользователя с сериализованной формы данных и он получает ответ. Затем, получив ответ, он добавляет данные к элементу класса твитов.
Если мы откроем пользовательский поиск в браузере, он будет выглядеть как на следующем скриншоте:
Но подождите! Что случится с этой формой при отправке? В AJAX-запрос отправляется метод post () класса search, который является следующим:
def post(self, request):
form = SearchForm(request.POST)
if form.is_valid():
query = form.cleaned_data['query']
tweets = Tweet.objects.filter(text__icontains==query)
context = Context({"query": query, "tweets": tweets})
return_str = render_to_string('partials/_tweet_search.html', context)
return HttpResponse(json.dumps(return_str), content_type="application/json")
else:
HttpResponseRedirect("/search")
Мы проверяем правильность формы после того, как мы извлекаем из запроса метод request.POST; Если форма является валидной, запрос извлекается из объекта Form.
Затем, метод tweets = Tweet.objects.filter(text__icontains==query) ищет совпадение подстроки для данного термина запроса.
Поиски проводятся с помощью метода под названием filter(text__icontains==query)в модуле Tweet.objects .Вы можете подумать о нем как об эквиваленте оператора SELECT в модели Django. Он получает критерии поиска в качестве своих аргументов и возвращает результат поиска.Имя каждого аргумента должно придерживаться следующего контекста именования:
field__operator
Обратите внимание, что переменные field и operator разделяются двумя нижними подчеркиваниями: поле, которое является именем поля, которое мы хотим искать, и оператор, который является методом поиска, который мы хотим использовать. Вот список часто используемых операторов:
Кроме того, существуют версии нечувствительные к регистру первых трех операторов: iexact, icontains и istartswith, которые могут быть также включены в список.
Единственное, что мы делаем совершенно по разному,следующее:
context = Context({"query": query, "tweets": tweets})
return_str = render_to_string('partials/_tweet_search.html', context)
return HttpResponse(json.dumps(return_str), content_type="application/json")
Нашей целью было загрузить результаты поиска без перезагрузки или обновления на странице поиска. Если это так, тогда как наши предыдущий метод отображения поможет нам? Он не поможет. Нам нужны некоторые методы, которые могут помочь отправить данные браузеру без его перезагрузки.
Мы широко используем концепции в веб-разработке под названием partials. Это, как правило, небольшие фрагменты HTML-кода, созданные на стороне сервера, отображаемые как JSON, а затем они добавляются к существующей модели DOM с помощью JavaScript.
Чтобы реализовать этот метод, мы сначала создадим каталог под названием partials в существующей папке templates, файл _tweet_search.html со следующим содержимым:
{% for tweet in tweets %}
<div class="well">
<span>{{ tweet.text }}</span>
</div>
{% endfor %}
{% if not tweets %}
<div class="well">
<span> Не найдено твитов.</span>
</div>
{% endif %}
Код будет отображать весь объект tweet в поле well или, если не найден объект tweet, он будет отображать внутри окна well Не найдено твитов.
Вышеприведенная концепция отображает partials как строки в представлении, и если мы должны передать какие-либо параметры для отображения, мы должны передать их в первую очередь с вызовом для создания строки из partials. Чтобы передать параметры partials, нам нужно создать объект контекста и затем передать наши параметры:
context = Context({"query": query, "tweets": tweets})
return_str = render_to_string('partials/_tweet_search.html', context)
Таким образом, мы будем создавать контекст с запросом (который мы будем использовать позже) и параметры tweets и использовать функцию render_to_string (). Затем мы можем использовать JSON для дампа строки в функцию HttpResponse ():
return HttpResponse(json.dumps(return_str), content_type="application/json")
Список импорта являются следующим:
from django.views.generic import View,TemplateView from django.shortcuts import render from user_profile.models import User, UserFollower from tweet.models import Tweet, HashTag from tweet.forms import TweetForm, SearchForm, SearchHashTagForm from django.http import HttpResponseRedirect from django.template.loader import render_to_string from django.template import Context from django.http import HttpResponse import json
Вот оно что! Мы завершили базовый поиск на основе AJAX для поиска твитов.Поиск по слову django выдаст нам 3 твита, которые мы создали, так, как показано на следующем скриншоте:
Идите вперед и поиграйте с поисковой системой, и я уверен, что вы будете еще больше влюбитесь в Django.
Теперь у нас есть страница функционального (хотя и очень простого) поиска. В течение последующих глав будет улучшена функциональность поиска, сам, но сейчас для нас главное ввести AJAX в форму поиска, так чтобы результаты были получены за кулисами и представлены пользователю без перезагрузки страницы. Благодаря нашему модулярному коду, эта задача окажется намного проще, чем это может показаться.
Автозавершение тегов является последним расширением AJAX, которое мы осуществим в этой главе. Концепция автозавершения нашла свой путь среди веб-приложений, когда Google выпустила свой интерфейс предугадывания поисковых запросов. Предугадывание показывает самые популярные поисковые запросы, ниже поле ввода поиска, основанные на том, что пользователь вводит. Это также похоже на то, как редакторы кода в интегрированных средах разработки автоматически завершают код, основываясь на том, что вы вводите. Эта возможность экономит время, позволяя пользователю напечатать несколько символов слова, которое они хотят напечатать и затем позволяет им выбрать его из списка без необходимости вводить его в полностью.
Мы имплементируем эту функцию предлагая преположительные варианты, когда пользователь вводит теги при отправке, но вместо того чтобы писать эту особенность с нуля, мы собираемся использовать плагин jQuery для его реализации .jQuery располагает большим и постоянно растущим списком плагинов, которые предоставляют разнообразные возможности Установка плагина является ничем не отличается от установки самого jQueiy. Вы скачиваете один (или более) файлов и привязываете их к вашему шаблону и вы должны написать несколько строк кода JavaScript, чтобы активировать плагин.
Вы можете просматривать список доступных jQuery плагинов, перейдя на http://docs.jquery.com/plugins. Найдите в списке плагин автозаполнения и скачайте его, или вы можете взять его непосредственно на http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/.
Вы получите zip-архив с большим количеством файлов в нем. Извлеките файлы (которые можно найти в каталоге jquery/autocomplete/scroll) в каталог static/js:
Поскольку мы хотим предложить функцию автозаполнения на странице представления закладки, создайте пустой файл под названием tag_autocomplete.js в папке js. Затем откройте файл template/bookmark_save.html и и свяжите все предыдущие файлы в нем:
{% extends "base.html" %}
{% block external %}
<link rel="stylesheet"
href="/site_media/jquery.autocomplete.css" type="text/css" />
<script type="text/javascript"
src="/site_media/dimensions.js"> </script>
<script type="text/javascript"
src="/site_media/j query.bgiframe.min.j s"> </script>
<script type="text/javascript"
src="/site_media/j query.autocomplete.j s"> </script>
<script type="text/javascript"
src="/site_media/tag_autocomplete.js"> </script>
{% endblock %}
{% block title %}Save Bookmark{% endblock %}
{% block head %}Save Bookmark{% endblock %}
[. . .1
Теперь мы закончили установку плагина, и, если вы прочитаете документацию о нем, вы обнаружите что что этот плагин активирован путем вызова метода с именем autocomplete () на выбранный элемент ввода. Функция autocomplete () принимает следующие параметры:
Перед активацией плагина, нам нужно написать представление, которое получает входные данные пользователя и возвращает набор предложений .Откройте файл tweets/view.py и добавьте следующее в конце:
def AJAX_tag_autocomplete(request):
if request.GET.has_key(‘q’):):):
tags = \
Tag.objects.filter(name istartswith=request.GET [‘q’]) [:10]
return HttpResponse('\n'.join(tag.name for tag in tags))
return HttpResponse()
Плагин autocomplete() отправляет пользовательский ввод в GET-переменную с именем q. Таким образом, мы можем убедиться, что эта переменная существует и построить список тегов, имена которых начинаются со значения этой переменной. Это сделано с помощью метода filter() и оператора istartswith, о котором мы узнали ранее в главе. Мы выберем только первые десять результатов чтобы избежать ошеломления пользователя предложениями и снизить расходы на пропускную способность и производительность. Наконец мы соединяем предложения в одну строку, разделенные знаками новой строки, переносим строки в объект HttpResponse и возвращаем его.
Так как представление готово, добавим запись о плагине в файл, как показано ниже:
urlpattems = patterns ('
# AJAX
(r'^AJAX/tag/autocomplete/$', AJAX_tag_autocomplete),
)
Теперь Активируйте плагин на поле ввода тегов, введя следующий код в файл js/tag_autocomplete.js:
$(document).ready(function () {
$("#id_tags").autocomplete(
'/AJAX/tag/autocomplete/',
{multiple: true, multipleSeparator: 1 '}
) ;
}>;
Код передает анонимную функцию методу $(document).ready (). Эта функция вызывает функцию autocomplete() на поле ввода тегов, передает аргументы, о которых мы говорили ранее.
Эти несколько строк кода - все, что нам нужно для того, чтобы имплементировать автоматическое заполнение тегов. Чтобы проверить новую функцию, перейдите к http: //127.0.0.l: 8000/save/ и попробуйте ввести символ или два в поле тегов. Предложения должны появиться основе тегов доступных в вашей базе данных.
На этой функции мы и закончим эту лекцию. Мы охватили много материала и узнали о многих интересных технологиях и техниках. После прочтения этой главы, вы должны быть способны задумать и осуществить многие другие улучшения пользовательского интерфейса, например, способность удалять закладки из страницы пользователя или живой просмотр закладок по тэгам и многие многих другие вещи.
Следующая лекция будет рассказывать о другой теме: мы позволим пользователям голосовать и комментировать свои любимые закладки и на первой странице нашего приложения не останется так пусто, как сейчас!
Контрольные вопросы
Упражнения
Упражнение 1.
Добавьте живой поиск по твитам
Упражнение 2.
Измените код таким образом, чтобы результаты поиска отображались на отдельной странице
Упражнение 3.
Добавьте возможность поиска твитов с учетов даты
Упражнение 4.
Добавьте возможность регистрации пользователей
Список тем курсовых работ
Краткие итоги
Цель лекции: рассмотреть основы технологии AJAX, познакомиться с понятием формы, рассмотреть основные типы виджетов, создать страницу поиска твитов, познакомиться с методами jQuery, добавить автодополнение хэштегов при отправке твита.
Ключевые термины: AJAX, CSS, HTML, jQuery, форма, фреймворк, твит, хештег, имплементация, элемент, запрос, поиск, метод, атрибут, приложение.
Появление AJAX стало важной вехой в истории Веб 2.0. AJAX — это группа технологий, что позволяет разработчикам создавать интерактивные, с большими возможностями веб-приложения. Большинство из этих технологий были доступны за многие годы до появления самого AJAX. Однако появление AJAX представляет переход Web от статических страниц, которые необходимо обновлять всякий раз, когда происходил обмен данными к динамическим, гибким и интерактивным пользовательским интерфейсам.
Так как наш проект является приложением Веб 2.0, оно должно быть более нацелено на пользователей. Успех нашего приложения зависит от получения пользователем возможности размещать и обмениваться контентом на нем. Таким образом, пользовательский интерфейс нашего приложения является одной из наших основных проблем. Эта лекция улучшит интерфейс нашего приложения с помощью описания возможностей AJAX, что сделает его более удобным для пользователей и интерактивным.
AJAX, которая расшифовывается как Asynchronous JavaScript and XML (Асинхронный JavaScript и XML), состоит из следующих технологий:
Иногда используется XML, но это может быть в HTML, обычном тексте или формате на основе JavaScript, называемом JSON.
AJAX технологии позволяют кодировать обмен данными на клиентской стороне с сервером за кулисами, без перезагрузки всей страницы каждый раз, когда пользователь делает запрос. С помощью AJAX, веб-разработчик может увеличить интерактивность и удобство использования ' веб-страниц.
AJAX обеспечивает следующие преимущества при имплементации в правильных местах:
Существует множество примеров веб-приложений, использующих AJAX: карты Google и Gmail, возможно, два наиболее известных примера. В самом деле, эти два приложения играют важную роль в распространении использования AJAX из-за того успеха, которыми они пользуются. Что отличает Gmail от других почтовых сервисов, это его пользовательский интерфейс, который позволяет пользователям интерактивно управлять электронной почтой, не дожидаясь перезагрузки страницы после каждого действия, и это создает лучший пользовательский опыт и позволяет Gmail чувствовать себя отзывчивым и многофункциональным приложением, нежели простой веб-сайт.
В этой лекции объясняется, как использовать AJAX с Django, с тем чтобы сделать приложения более гибким и удобным для пользователей. Мы имплементируем три наиболее распространенных функции AJAX, которые могут быть сегодня найдены в веб-приложениях. Однако, прежде, мы узнаем о преимуществах использования инфраструктуры AJAX, в отличие от работы с raw JavaScript функциями.
Так как мы уже использовали bootstrap в нашем проекте, нам не нужно настраивать его отдельно для AJAX и jQuery.
Есть много преимуществ использования AJAX фреймворка:
Без инфраструктуры AJAX разработчики должны отслеживать поддержку браузера для возможностей JavaScript, которые они используют и должны работать вокруг ограничений, которые присутствуют в некоторых браузерах для выполнения JavaScript.
С другой стороны, при использовании фреймворка AJAX, фреймворк заботится об этом для нас; он абстрагирует доступ к имплементации JavaScript и сделок с шин различия и особенности JavaScript в браузерах. Банки металлические способом, мы можем сосредоточиться на разработке функции вместо тревожиться о браузере различия и ограничения.
Поэтому даже если вы не решитесь использовать инфраструктуру AJAX, вы найдете для себя написание библиотеки функций, которая инкапсулирует JavaScript зал и делает их более удобными. Однако, зачем изобретать велосипед, когда много отличных библиотек open source уже доступно?
AJAX фреймворки, имеющихся на рынке сегодня варьируются от всеобъемлющих решений, которые предоставляют серверные и клиентские компоненты до легких клиентских библиотек, которые упрощают работу с JavaScript. Учитывая, что мы уже используем Django на серверной стороне, мы хотим фреймворк только с клиентской стороны. В дополнение к этому фреймворк должны быть легко интегрируем с Django без требования любых дополнительных зависимостей. Наконец, желательно, выбрать легкий и быстрый фреймворк. Есть множество отличных фреймворков, которые отвечают нашим требованиям, таких как Prototype, Yahoo! UI Library, и jQuery.
Однако для нашего приложения, я собираюсь выбрать jQuery, потому что это самый легкий фреймворк из трех. Он также весьма активно развивается сообществом и имеет широкий спектр плагинов. Если у вас уже есть опыт с другим фреймворком, вы можете продолжить использовать его во время этой главы. Правда, вам придется адаптировать JavaScript код в этой главе под ваш фреймворк, но код Django на стороне сервера останется таким же, независимо от того, какой фреймворк вы выберете.
Вам нужно также импортировать bootstrap и jQuery.Таким образом, не нужно никакой особой установки или импорта для использования функций AJAX в нашем проекте Django.
Прежде чем мы начнем имплементировать улучшения AJAX в наш проект, давайте пройдем через краткое введение в основы jQuery.
jQuery — это библиотека функций JavaScript, которая облегчает взаимодействие с HTML-документами и управляет им. Библиотека предназначена для сокращения времени и усилий на написание кода и достижения совместимости между браузерами, и в то же время она в полной мере использует то, что JavaScript предлагает для создания гибких и интерактивных веб-приложений.
Рабочий процесс с помощью jQuery в общем состоит из следующих двух этапов:
jQuery предоставляет простой подход для выбора элементов: она работает путем передачи строки селектора CSS в функцию $ (). Ниже приведены некоторые примеры, которые иллюстрируют использование этой функции :
Функция $ () создает и возвращает объект jQuery.После этого можно вызывать методы этого объекта для взаимодействия с выбранным HTML-элементом.
jQuery предлагает разнообразные методы для обработки HTML документов. Вы можете скрыть или показать элементы, присоединить обработчики событий к событиям, изменять свойства CSS, манипулировать структурой страницы и, самое главное, формировать AJAX-запросы.
Для отладки, мы выберем браузер Internet Explorer как браузер нашего выбора. Internet Explorer является одним из самых передовых JavaScript отладчиком в виде его инструментов разработчика Django. Чтобы запустить его, нажмите на клавиатуре Ctrl + Shift + J.
Поэкспериментируем с методами, изложенными в этом разделе, запустим сервер разработки и перейдем на страницу профиля пользователя (http: //127.0.0.1:8000/user/test/). Откройте консоль инструментов(нажав на клавиатуре Ctrl + Shift + J) разработчика и нажмите F12, попробуйте выбрать элементов и манипулировать ими.
Скрытие и отображение элементов
Давайте начнем с чего-то простого. Чтобы скрыть элемент на странице, вызовите метод — hide() на нем.Чтобы показать его снова, вызовите метод show(). Например попробуйте это с меню навигации, называемом navbar в загрузчик приложения:
>>> $(".navbar").hide()
>>> $(".navbar").show()
Также можно анимировать элемент во время скрытия и показа его. Попробуйте fadeOut(), fadeln(), slideUp() или slideDown () — методы, чтобы увидеть два из этих анимационных эффекта.
Конечно эти методы (как и все другие методы jQuery) также работают, если вы выберете более одного элемента за один раз. Например, если открыть профиль пользователя и ввести следующий вызов метода в консоли средства разработчика, все твиты исчезнут:
>>> $(".well").slideUp()
Далее мы узнаем, как изменить свойства CSS элементов. jQuery предлагает метод, называемый css() для выполнения CSS операций. Если вызвать этот метод с именем свойства CSS, переданным в виде строки, она возвращает значение этого свойства:
>>> $(".navbar").css("display")
Результатом этого является следующее:
block
Если второй аргумент передается в этот метод, он задает указанное свойство CSS выбранного элемента для дополнительного аргумента:
>>> $(".navbar").css("font-size", "0.8pt")
Результатом этого является следующее сообщение:
<div id="nav" style="font-size: 0.8em;"></div>
В самом деле вы можете манипулировать любой атрибут м HTML и не только свойствами CSS. Чтобы сделать это, используйте метод attr(), который работает аналогично методу css(). Вызвав его по имени атрибута, он возвращает значение атрибута, в то время как его вызов с именем атрибута или пары значений задает атрибуту переданное значение:
>>> $("input").attr ("size", "48")
Это приводит к следующему:
<input id="idcountry" name="country" type="hidden" value="Global" size="48"> <input type="submit" value="post" size="48">
Это одновременно изменит размер всех входных элементов на 48.
В дополнение к этому, есть методы ярлыка, чтобы получать и устанавливать часто используемые атрибуты, такие как val(), который возвращает значение поля ввода, когда вызывается без аргументов и задает значение для аргумента, если вы передадите аргумент. Существует также метод html() для контроля HTML кода внутри элемента.
Наконец, существует два метода, которые могут использоваться для присоединения или отсоединения CSS класса для элемента: это методы addClass() и removeClass(). Третий метод служит для переключения CSS класса и он называется методом toggleClass (). Все эти методы класса принимают имя класса, который необходимо изменить как параметр.
Теперь, когда вам удобно манипулировать HTML-элементами, давайте посмотрим, как добавлять новые элементы или удалить существующие элементы. Чтобы вставить HTML-код перед элементом, используйте метод before(), а для вставки кода после элемента, используйте метод after().Обратите внимание, как методы jQuery хорошо именованы и их очень легко запомнить!
Давайте протестируем эти методы, вставив скобки вокруг списков тегов на странице пользователя. Откройте вашу пользовательскую страницу и введите следующее в консоли средств разработчика:
>>> $(".well span").before ("<strong>(</strong>")
>>> $(".well span").after ("<strong>)</strong>")
Вы можете передать любую строку, какую вы хотите, с методами before() или after(). Строка может содержать обычный текст, один или больше элементов HTML. Эти методы предоставляют очень гибкий способ для динамического добавления элементов HTML в документ HTML.
Если вы хотите удалить элемент, используйте метод remove(). Например:
$("#navbar").remove()
Этот метод не только скрывает элемент, он также удаляет его полностью из дерева документов. Если вы попытаетесь выбрать элемент снова, после использования метода remove (), вы получите пустой набор:
>>> $("#nav")
Результатом этого является следующим:
[]
Конечно, это только удаляет элементы из текущего экземпляра страницы. Если вы обновите страницу, элементы появятся снова.
Хотя CSS селекторы предоставляют очень мощный способ для выбора элементов, бывают случаи, когда вы можете захотеть обойти дерево документа, начиная от конкретного элемента.
Для этого jQuery предоставляет несколько методов. Метод parent () возвращает родителя текущего выбранного элемента. Метод children () возвращает всех непосредственных дочерних элементов выбранного элемента. Наконец, метод find () возвращает всех потомков текущего выбранного элемента. Все эти методы принимают необязательную строку CSS селектора для ограничения элементов теми, которые соответствуют результату селектора. Например, $(".column").find("span") возвращает всех потомков <span> столбца aclass.
Если вы хотите получить доступ к отдельному элементу группы, используйте метод get (), который принимает индекс элемента в качестве параметра. Метод $("span").get(0), например, возвращает первый элемент <span> из выбранной группы.
Далее мы изучим обработчики событий. Обработчик событий — это функция JavaScript, которая вызывается, когда происходит определенное событие, например, при нажатии кнопки или отправке формы. jQuery предоставляет большой набор методов для присоединения обработчиков к событиям; события, представляющие особый интерес в нашем приложении - щелчки мышью и отправка формы. Для обработки события нажатия на элемент, мы выбираем этот элемент и вызываем метод click(). Этот метод принимает в качестве параметра функцию обработчика событий. Давайте попробуем это в нашей консоли разработчика.
Откройте страницу профиля пользователя приложения и вставьте кнопку после твита:
>>> $(".well span").after("cbutton id=\"test-button\">Нажми!</ button>")
Обратите внимание, что нам пришлось опустить кавычки в строках переданных методу after().
Если вы попытаетесь нажать кнопку, ничего не произойдет, так что давайте присоединим обработчик событий к нему:
>>> $("#test-button").click(function () { alert("Вы меня нажали!"); })
Теперь, когда вы нажмете на кнопку,появится окно сообщения.Как это работает?
Аргумент, который мы передали в методе click(), может выглядеть немного сложным, так что давайте рассмотрим его снова:
function () { alert("Вы меня нажали!"); }
Кажется, что это должно быть объявлением функции, но без имени функции. Действительно эта конструкция создает так называемую анонимную функцию в терминологии JavaScript, и она используется, когда вам нужно создать функцию на лету и передать ее в качестве аргумента другой функции. Мы могли бы избежать с помощью анонимных функций и объявить обработчик события как обычную функцию
>>> function handler{ alertC("Вы нажали меня!"); }
>>> $("#test-button").click(handler)
Предыдущий код достигает того же эффекта, но первый является более кратким и компактным. Я настоятельно рекомендую вам привыкнуть к анонимным функциям в JavaScript (если вы еще не привыкли), как я уверен, что вы оцените эту конструкцию и найдете ее более удобной для чтения после использования его некоторое время.
Обработка формы отправки очень похоже на обработку щелчков мыши. Сначала выберите форму, затем вызовите метод отправки на нее, и затем передайте обработчик в качестве аргумента. Мы будем использовать этот метод несколько раз во время добавления функций AJAX к нашему проекту в последующих разделах.
Прежде чем мы закончим этот раздел, давайте поговорим о AJAX-запросах. jQuery предоставляет много способов, чтобы отправлять запросы AJAX на сервер. Существует, например, метод load(), который принимает URL-адрес и загружает страницу по URL-адресу в выбранный элемент. Существуют также методы для отправки запросов GET или POST и получения результатов. Мы изучим эти методы более подробно при имплементации функций AJAX в наш проект.
Мы будем постепенно вводить AJAX в наше приложение путем реализации живого поиска. Идея эта функции проста: когда пользователь вводит несколько ключевых слов в текстовое поле и нажимает на поиск, за кулисами срабатывает сценарий, чтобы получить результаты поиска и представить их на той же странице. Страница поиска не перезагружается, таким образом экономя пропускную способность и обеспечивая лучший и более отзывчивый опыт пользователя.
Прежде чем мы постепенно это реализуем, нам нужно иметь в виду одно важное правило работы с AJAX: напишите приложение, так чтобы оно работало без AJAX и затем предоставьте к нему AJAX. Если вы сделаете это, вы убедитесь, что каждый будет иметь возможность использовать ваше приложение, включая пользователей, которые не имеют JavaScript, а также включая и тех, кто используют браузеры без поддержки AJAX.
Так что прежде чем мы поработаем с AJAX давайте напишите простое представление, чтобы искать по названию закладки. Во-первых нам нужно создать форму поиска, поэтому откройте файл tweets/forms.py и добавьте в него следующий класс:
Сlass SearchForm(forms.Form):
query = forms.CharField(label='Enter a keyword to search for',
widget=forms.TextInput(attrs={'size': 32, 'class':'form-control search-query'}))
Как вы можете видеть, это довольно простой класс формы с только одним текстовым полем. Это поле будет использоваться пользователем для ввода ключевых слов поиска. Далее создадим представление для проведения поиска. Откройте файл tweets/views.py и введите следующий код в него:
class Search(View):
"""Search all tweets with query /search/?query=<query> URL"""
def get(self, request):
form = SearchForm()
params = dict()
params["search"] = form
return render(request, 'search.html', params)
def post(self, request):
form = SearchForm(request.POST)
if form.is_valid():
query = form.cleaned_data['query']
tweets = Tweet.objects.filter(text__icontains=query)
context = Context({"query": query, "tweets": tweets})
return_str = render_to_string('partials/_tweet_search.html', context)
return HttpResponse(json.dumps(return_str), content_type="application/json")
else:
HttpResponseRedirect("/search")
Помимо нескольких вызовов метода представление должно быть очень легко для понимания.
Если вы посмотрите на запрос GET, здесь все довольно просто, он подготавливает форму поиска и затем отображает ее.
Метод post() является тем методом где происходит волшебство. Когда мы отображаем результаты поиска, это просто макета отображения с формой поиска, так что если вы взглянете на новый файл, который мы создали, под названием search.html, вы можете увидеть следующее:
{% extends "base.html" %}
{% load staticfiles %}
{% block content %}
<div class="row clearfix">
<div class="col-md-6 col-md-offset-3 column">
<form id="search-form" action="" method="post">{% csrf_token %}
<div class="input-group input-group-sm">
{{ search.query.errors }}
{{ search.query }}
<span class="input-group-btn">
<button class="btn btn-search" type="submit">search</button>
</span>
</div><!-- /input-group -->
</form>
</div>
<div class="col-md-12 column tweets">
</div>
</div>
{% endblock %}
{% block js %}
<script src="{% static 'js/search.js' %}"></script>
{% endblock %}
Если вы посмотрите внимательно, вы увидите, что мы включили новый раздел раздела с именем {% block js %}. Концепция, используемая здесь, является такой же, как и {% block content %}, то есть, то что объявляется здесь, будет передаваться в файл base.html. Взяв это на заметку, посмотрим на измененный файл base.html. Мы увидим следующее:
{% load staticfiles %}
<html>
<head>
<link href="{% static 'css/bootstrap.min.css' %}"
rel="stylesheet" media="screen">
{% block css %}
{% endblock %}
</head>
<body>
<nav class="navbar navbar-default" role="navigation">
<a class="navbar-brand" href="#">MyTweets</a>
{% block navbar %}
{% endblock %}
</nav>
<div class="container">
{% block content %}
{% endblock %}
</div>
<nav class="navbar navbar-default navbar-fixed-bottom" role="navigation">
<p class="navbar-text navbar-right">Footer </p>
</nav>
<script src="{% static 'js/jquery-2.1.1.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<script src="{% static 'js/base.js' %}"></script>
{% block js %}
{% endblock %}
</body>
</html>
Предыдущий код ясно показывает два новых блока содержимого, а именно:
{% block css %}
{% endblock %}
{% block js %}
{% endblock %}
Они используются для включения типов соответствующих файлов и для отображения типы файлов с основы, так что поддержка проекта становится намного проще с помощью простого правила объявлять только один файл CSS и JavaScript на странице. Мы осуществим это позже в книге с концепцией, называемой assets pipeline.
Теперь, возвращаясь к нашей функции поиска AJAX, вы увидите, что этот файл search.html, аналогичен файлу tweet.html.
Для функции поиска мы создадим новый URL-адрес, который нам нужно добавить к файлу urls.py следующим образом:
url(r'^search/$', Search.as_view())
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from tweet.views import Index, Profile, PostTweet, HashTagCloud, Search
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', Index.as_view()),
url(r'^user/(\w+)/$', Profile.as_view()),
url(r'^admin/', include(admin.site.urls)),
url(r'^user/(\w+)/post/$', PostTweet.as_view()),
url(r'^hashTag/(\w+)/$', HashTagCloud.as_view()),
url(r'^search/$', Search.as_view()),
)
В файле search.html мы определили метод search.js; давайте создадим этот файл Javascript, чтобы действительно выполнялся запрос AJAX
$('#search-form').submit(function(e){
$.post('/search/', $(this).serialize(), function(data){
$('.tweets').html(data);
});
e.preventDefault();
});
Этот код JavaScript срабатывает при отправке формы, это формирует AJAX запрос post к /search пользователя с сериализованной формы данных и он получает ответ. Затем, получив ответ, он добавляет данные к элементу класса твитов.
Если мы откроем пользовательский поиск в браузере, он будет выглядеть как на следующем скриншоте:
Но подождите! Что случится с этой формой при отправке? В AJAX-запрос отправляется метод post () класса search, который является следующим:
def post(self, request):
form = SearchForm(request.POST)
if form.is_valid():
query = form.cleaned_data['query']
tweets = Tweet.objects.filter(text__icontains==query)
context = Context({"query": query, "tweets": tweets})
return_str = render_to_string('partials/_tweet_search.html', context)
return HttpResponse(json.dumps(return_str), content_type="application/json")
else:
HttpResponseRedirect("/search")
Мы проверяем правильность формы после того, как мы извлекаем из запроса метод request.POST; Если форма является валидной, запрос извлекается из объекта Form.
Затем, метод tweets = Tweet.objects.filter(text__icontains==query) ищет совпадение подстроки для данного термина запроса.
Поиски проводятся с помощью метода под названием filter(text__icontains==query)в модуле Tweet.objects .Вы можете подумать о нем как об эквиваленте оператора SELECT в модели Django. Он получает критерии поиска в качестве своих аргументов и возвращает результат поиска.Имя каждого аргумента должно придерживаться следующего контекста именования:
field__operator
Обратите внимание, что переменные field и operator разделяются двумя нижними подчеркиваниями: поле, которое является именем поля, которое мы хотим искать, и оператор, который является методом поиска, который мы хотим использовать. Вот список часто используемых операторов:
Кроме того, существуют версии нечувствительные к регистру первых трех операторов: iexact, icontains и istartswith, которые могут быть также включены в список.
Единственное, что мы делаем совершенно по разному,следующее:
context = Context({"query": query, "tweets": tweets})
return_str = render_to_string('partials/_tweet_search.html', context)
return HttpResponse(json.dumps(return_str), content_type="application/json")
Нашей целью было загрузить результаты поиска без перезагрузки или обновления на странице поиска. Если это так, тогда как наши предыдущий метод отображения поможет нам? Он не поможет. Нам нужны некоторые методы, которые могут помочь отправить данные браузеру без его перезагрузки.
Мы широко используем концепции в веб-разработке под названием partials. Это, как правило, небольшие фрагменты HTML-кода, созданные на стороне сервера, отображаемые как JSON, а затем они добавляются к существующей модели DOM с помощью JavaScript.
Чтобы реализовать этот метод, мы сначала создадим каталог под названием partials в существующей папке templates, файл _tweet_search.html со следующим содержимым:
{% for tweet in tweets %}
<div class="well">
<span>{{ tweet.text }}</span>
</div>
{% endfor %}
{% if not tweets %}
<div class="well">
<span> Не найдено твитов.</span>
</div>
{% endif %}
Код будет отображать весь объект tweet в поле well или, если не найден объект tweet, он будет отображать внутри окна well Не найдено твитов.
Вышеприведенная концепция отображает partials как строки в представлении, и если мы должны передать какие-либо параметры для отображения, мы должны передать их в первую очередь с вызовом для создания строки из partials. Чтобы передать параметры partials, нам нужно создать объект контекста и затем передать наши параметры:
context = Context({"query": query, "tweets": tweets})
return_str = render_to_string('partials/_tweet_search.html', context)
Таким образом, мы будем создавать контекст с запросом (который мы будем использовать позже) и параметры tweets и использовать функцию render_to_string (). Затем мы можем использовать JSON для дампа строки в функцию HttpResponse ():
return HttpResponse(json.dumps(return_str), content_type="application/json")
Список импорта являются следующим:
from django.views.generic import View,TemplateView from django.shortcuts import render from user_profile.models import User, UserFollower from tweet.models import Tweet, HashTag from tweet.forms import TweetForm, SearchForm, SearchHashTagForm from django.http import HttpResponseRedirect from django.template.loader import render_to_string from django.template import Context from django.http import HttpResponse import json
Вот оно что! Мы завершили базовый поиск на основе AJAX для поиска твитов.Поиск по слову django выдаст нам 3 твита, которые мы создали, так, как показано на следующем скриншоте:
Идите вперед и поиграйте с поисковой системой, и я уверен, что вы будете еще больше влюбитесь в Django.
Теперь у нас есть страница функционального (хотя и очень простого) поиска. В течение последующих глав будет улучшена функциональность поиска, сам, но сейчас для нас главное ввести AJAX в форму поиска, так чтобы результаты были получены за кулисами и представлены пользователю без перезагрузки страницы. Благодаря нашему модулярному коду, эта задача окажется намного проще, чем это может показаться.
Автозавершение тегов является последним расширением AJAX, которое мы осуществим в этой главе. Концепция автозавершения нашла свой путь среди веб-приложений, когда Google выпустила свой интерфейс предугадывания поисковых запросов. Предугадывание показывает самые популярные поисковые запросы, ниже поле ввода поиска, основанные на том, что пользователь вводит. Это также похоже на то, как редакторы кода в интегрированных средах разработки автоматически завершают код, основываясь на том, что вы вводите. Эта возможность экономит время, позволяя пользователю напечатать несколько символов слова, которое они хотят напечатать и затем позволяет им выбрать его из списка без необходимости вводить его в полностью.
Мы имплементируем эту функцию предлагая преположительные варианты, когда пользователь вводит теги при отправке, но вместо того чтобы писать эту особенность с нуля, мы собираемся использовать плагин jQuery для его реализации .jQuery располагает большим и постоянно растущим списком плагинов, которые предоставляют разнообразные возможности Установка плагина является ничем не отличается от установки самого jQueiy. Вы скачиваете один (или более) файлов и привязываете их к вашему шаблону и вы должны написать несколько строк кода JavaScript, чтобы активировать плагин.
Вы можете просматривать список доступных jQuery плагинов, перейдя на http://docs.jquery.com/plugins. Найдите в списке плагин автозаполнения и скачайте его, или вы можете взять его непосредственно на http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/.
Вы получите zip-архив с большим количеством файлов в нем. Извлеките файлы (которые можно найти в каталоге jquery/autocomplete/scroll) в каталог static/js:
Поскольку мы хотим предложить функцию автозаполнения на странице представления закладки, создайте пустой файл под названием tag_autocomplete.js в папке js. Затем откройте файл template/bookmark_save.html и и свяжите все предыдущие файлы в нем:
{% extends "base.html" %}
{% block external %}
<link rel="stylesheet"
href="/site_media/jquery.autocomplete.css" type="text/css" />
<script type="text/javascript"
src="/site_media/dimensions.js"> </script>
<script type="text/javascript"
src="/site_media/j query.bgiframe.min.j s"> </script>
<script type="text/javascript"
src="/site_media/j query.autocomplete.j s"> </script>
<script type="text/javascript"
src="/site_media/tag_autocomplete.js"> </script>
{% endblock %}
{% block title %}Save Bookmark{% endblock %}
{% block head %}Save Bookmark{% endblock %}
[. . .1
Теперь мы закончили установку плагина, и, если вы прочитаете документацию о нем, вы обнаружите что что этот плагин активирован путем вызова метода с именем autocomplete () на выбранный элемент ввода. Функция autocomplete () принимает следующие параметры:
Перед активацией плагина, нам нужно написать представление, которое получает входные данные пользователя и возвращает набор предложений .Откройте файл tweets/view.py и добавьте следующее в конце:
def AJAX_tag_autocomplete(request):
if request.GET.has_key(‘q’):):):
tags = \
Tag.objects.filter(name istartswith=request.GET [‘q’]) [:10]
return HttpResponse('\n'.join(tag.name for tag in tags))
return HttpResponse()
Плагин autocomplete() отправляет пользовательский ввод в GET-переменную с именем q. Таким образом, мы можем убедиться, что эта переменная существует и построить список тегов, имена которых начинаются со значения этой переменной. Это сделано с помощью метода filter() и оператора istartswith, о котором мы узнали ранее в главе. Мы выберем только первые десять результатов чтобы избежать ошеломления пользователя предложениями и снизить расходы на пропускную способность и производительность. Наконец мы соединяем предложения в одну строку, разделенные знаками новой строки, переносим строки в объект HttpResponse и возвращаем его.
Так как представление готово, добавим запись о плагине в файл, как показано ниже:
urlpattems = patterns ('
# AJAX
(r'^AJAX/tag/autocomplete/$', AJAX_tag_autocomplete),
)
Теперь Активируйте плагин на поле ввода тегов, введя следующий код в файл js/tag_autocomplete.js:
$(document).ready(function () {
$("#id_tags").autocomplete(
'/AJAX/tag/autocomplete/',
{multiple: true, multipleSeparator: 1 '}
) ;
}>;
Код передает анонимную функцию методу $(document).ready (). Эта функция вызывает функцию autocomplete() на поле ввода тегов, передает аргументы, о которых мы говорили ранее.
Эти несколько строк кода - все, что нам нужно для того, чтобы имплементировать автоматическое заполнение тегов. Чтобы проверить новую функцию, перейдите к http: //127.0.0.l: 8000/save/ и попробуйте ввести символ или два в поле тегов. Предложения должны появиться основе тегов доступных в вашей базе данных.
На этой функции мы и закончим эту лекцию. Мы охватили много материала и узнали о многих интересных технологиях и техниках. После прочтения этой главы, вы должны быть способны задумать и осуществить многие другие улучшения пользовательского интерфейса, например, способность удалять закладки из страницы пользователя или живой просмотр закладок по тэгам и многие многих другие вещи.
Следующая лекция будет рассказывать о другой теме: мы позволим пользователям голосовать и комментировать свои любимые закладки и на первой странице нашего приложения не останется так пусто, как сейчас!
Контрольные вопросы
Упражнения
Упражнение 1.
Добавьте живой поиск по твитам
Упражнение 2.
Измените код таким образом, чтобы результаты поиска отображались на отдельной странице
Упражнение 3.
Добавьте возможность поиска твитов с учетов даты
Упражнение 4.
Добавьте возможность регистрации пользователей
Список тем курсовых работ
Краткие итоги
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.