LXF169: Web-разработка Django
Olkol (обсуждение | вклад) (→Управление) |
Olkol (обсуждение | вклад) м (Olkol переименовал страницу LXF168: Web-разработка Django в LXF169: Web-разработка Django) |
Текущая версия на 09:41, 14 ноября 2018
|
|
|
Каркас для web-приложений. Программирование в Django.
Содержание |
[править] Введение в Django
Джоно Бэкон закруляет серию несколькими советами профессионала.
В предыдущих трех частях этой серии о знакомстве с Django мы открыли несколько основных принципов создания мощного динамического web-приложения. Мы поговорили о настройке, базах данных, моделях, формах, задании URL-адресов, шаблонах, темах и др.
В этой четвертой и последней статье мы заполним ряд оставшихся в материалах пробелов и покопаемся в приемах и советах, способных вам пригодиться в повседневном программировании с Django. Эта статья предполагает наличие базовых знаний во многих из этих областей, и в ней я покажу вам некоторые решения ряда распространенных задач, которых в этой серии мы еще не касались.
[править] Новые трюки шаблонов
В предыдущей статье мы узнали, как построить интерфейс web-страницы с помощью шаблонов Django. Основы мы рассмотрели, но прочные знания языка шаблонов Django помогут вам создать лучший, более настраиваемый интерфейс.
При написании шаблонов важно хорошо знать два основных типа выражений: циклы и условия. Мы уже рассматривали циклы с циклом for:
{% for i in content %}
{% endfor %}
При отправке данных из представления шаблону обычно отправляется набор элементов, сгенерированный запросом, например, так:
content = MyTable.objects.all()
return render_to_response(‘mytemplate.html’, {‘content’: content}, context_instance=RequestContext(request))
Тут по ним можно пройтись в цикле for с приведенным выше синтаксисом. Иногда нам нужен больший контроль над отправляемыми шаблону данными. Скажем, в разных программах на Python структуры данных представляются по-разному. Если запрос подобен приведенному выше, вы получаете список элементов, по которому легко пройтись в цикле. Но иногда может понадобиться воспользоваться словарем – например, так:
{ “one” : 1, “two” : 2, “three” : 3 }
Тогда данные генерируются в представлении и затем отправляются странице точно таким же образом. Простой пример:
content = [ “one” : 1, “two” : 2, “three” : 3]
return render_to_response(‘mytemplate.html’, {‘content’: content}, context_instance=RequestContext(request))
Итерировать такие данные в шаблоне нужно немного иначе. Для этого воспользуемся следующим форматом:
{% for k, v in content.items %}
The key is Шаблон:K and the value is Шаблон:V
{% endfor %}
Здесь примечательны несколько моментов. Во-первых, мы используем конструкцию .items после указания массива content, по которому идут итерации – так мы получаем компоненты структуры данных. Затем мы получаем два компонента, поскольку это словарь, и k ссылается на ключ, а v – на значение. Можно сделать еще умнее – сформировать список словарей следующим образом:
content = [{ “one” : 1, “two” : 2 }, { “three” : 3 }, {“four” : 4 }]
Для итераций по нему нужно сначала создать цикл по внешнему списку, а внутри него выбирать каждый словарь и получать значения:
{% for item in content %}
{% for k, v in item.items %}
The key is Шаблон:K and the value is Шаблон:V
{% endfor %}
{% endfor %}
Еще один распространенный пример – словарь из словарей, например, при построении набора данных, которые относятся к чему-то. Например:
content = {
“bob” : { “job” : “Programmer”, “id” : 234},
“jane” : { “job” : “QA”, “id” : 245 },
}
Здесь у нас есть словарь для каждого лица, а в словаре – всякая информация об этом лице. Обратите внимание, что в каждом словаре используется один и тот же ключ (здесь – job). Позже мы посмотрим, как использовать операторы условия в таких структурах, а пока просто проитерируем его:
{% for name, info in content.items %}
Шаблон:Name
{% for k, v in info.items %}
{% endfor %}
{% endfor %}
У нас есть внешний цикл for, который проходит по именам и получает данные в переменных name и info, и внутренний цикл, который проходит по словарям из info.
Другая распространенная ситуация, в которой вы однажды окажетесь – создание структуры данных, объединяющей вместе данные моделей Django и другие данные. Пусть, например, у нас есть таблица People, и мы хотим добавить дополнительные данные в структуру данных. В представлении они создаются так:
people = People.objects.all()
content = {}
for person in people:
if person.clearance == 1:
content[person] = { “здание” : “штаб”, “знаетсекреты” : True }
else:
content[person] = { “здание” : “офис”, “знаетсекреты” : False }
return render_to_response(‘mytemplate.html’, {‘content’: content}, context_instance=RequestContext(request))
Здесь мы используем объект данных как ключ внешнего словаря, а значение – наш словарь. Скажем, если в People есть запись “Bob” и у Боба есть допуск, наша структура данных будет выглядеть так:
{ <People: Bob> : { “здание” : “штаб”, “знаетсекреты” : True } }
Итерироваться по ней можно так же, как в предыдущем примере, но можно обращаться к полям объекта данных. Например:
{% for name, info in content.items %}
Шаблон:Name.fullname has clearance level Шаблон:Name.clearance
{% for k, v in info.items %}
{% endfor %}
{% endfor %}
Эти примеры должны покрыть большинство ситуаций при итерировании данных различных типов в своих шаблонах.
[править] Условия и фильтры
Теперь переключим передачу и рассмотрим условия в фильтрах. Условия используются для проверки соответствия определенных переменных заданным значениям, и в зависимости от результата проверки можно отображать различную информацию.
Пусть, например, у нас в представлении имеется такая структура данных:
content = [ “admin”, “bob”, “jane” ]
Это простой список имен. Теперь в нашем шаблоне можно воспользоваться командой if, чтобы проверить, есть ли в списке администратор, и вывести для него другое сообщение:
{% for name in content %}
{% if name == “admin” %}
Admin logged in
{% else %}
Normal user logged in
{% endif %}
{% endfor %}
Другой способ это сделать – воспользоваться командой ifequal [если равно]:
{% for name in content %}
{% ifequal name “admin” %}
Admin logged in
{% else %}
Normal user logged in
{% endifequal %}
{% endfor %}
Еще одна приятная возможность шаблонов Django – широкий диапазон фильтров. Например, часто приходится отображать в таблице строки из базы данных, но если строк нет, нужно вывести соответствующее сообщение.
Для этого удобно воспользоваться фильтром length. Например, представьте, что нам нужно вывести список пользователей из таблицы People. Вот как можно проверить, есть ли в таблице записи, и вывести соответствующий результат:
{% ifequal content|length 0 %}
No people.
{% else %}
{% for name in content %}
{% ifequal name “admin” %}
Admin logged in
{% else %}
Normal user logged in
{% endifequal %}
{% endfor %}
{% endifequal %}
Здесь мы пользуемся обычным выражением ifequal, но применяем фильтр length к переменной content с помощью символа |.
В Django есть несколько полезных фильтров. Рассмотрим несколько самых популярных. Прежде всего, вам может понадобиться отображать даты в различных форматах – например, определить локаль пользователя и представить дату в соответствующем формате (например, 1-11-2013 вместо 11-1-2013). К объекту datetime можно применить фильтр date, например, так:
Он отформатирует дату следующим образом: Tue 08 Feb 2013. Буквы в этой строке определяют форматирование даты, и есть множество различных опций для того, чтобы представить дату именно так, как вам нужно. Еще два полезных фильтра – dictsort и dictsortreversed, он сортирует словарь, к которому применяется. Другие два – first и last, они возвращают первый и последний элементы списка. Некоторые полезные фильтры приведены во врезке «Памятка по фильтрам шаблонов».
[править] Добавление своих команд
В процессе работы с Django вы очень близко познакомитесь со скриптом manage.py, входящим в ваш проект. Чаще всего он используется для выполнения команд таким образом:
python manage.py syncdb
python manage.py runserver
manage.py – швейцарский армейский нож в арсенале Django. Он содержит команды для выполнения всевозможных действий: создания приложений, тестов, проверки моделей, исследования базы данных и др. Но иногда может возникнуть необходимость в собственных командах, которые можно выполнить с manage.py, например, когда нужно воспользоваться в своем проекте на Django функциями из другого проекта, не на Django.
Например, не так давно я начал проект «Достижения в Ubuntu [Ubuntu Accomplishments]» – это система, которая фиксирует ваши достижения и награждает вас призами за них. В рамках этого проекта я написал сервер проверки, который проверяет призы на подлинность для защиты от пользователей, подделывающих свои призы.
Потратив некоторое время на написание сервера проверки, я понял, что мне нужен способ визуализации ошибок и проблем, обнаруженных сервером. В качестве такого способа я выбрал клиент на Django и принялся за работу.
В процессе работы я столкнулся с проблемой: когда сервер проверки обнаружит ошибку – как добавить запись в базу данных Django, чтобы ее увидел клиент на Django? С одной стороны, можно было бы обновить базу данных вручную, подключившись к ней напрямую, но это неряшливый и штукарский подход. Затем я узнал, что можно создать пользовательскую команду для manage.py, которая бы это делала. Вот я и создал команду addfailure, и сервер проверки просто вызывал ее при возникновении ошибки и передавал команде информацию об ошибке. Посмотрим, как создать такую команду.
Эти различные команды manage.py связываются с приложением. Можно создать набор команд для каждого приложения в проекте. Например, предположим, что у нас есть проект Django для хранения списка сотрудников компании. В этом проекте есть модель ‘Staff [Штат]’, которая хранит список сотрудников. Предположим также, что приложение называется ‘company [компания]’.
[править] Управление
Пользовательскую функциональность, относящуюся к скрипту manage.py, назовем Management [Управлением]. Для начала нужно создать каталог management внутри нашего приложения, а затем, внутри этого каталога, каталог commands, где будут храниться наши команды (в данном случае, у нас получилось company/management/commands).
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
Теперь создадим пользовательскую команду и назовем ее addstaffmember [Добавить сотрудника]. Для этого создайте файл addstaffmember.py в каталоге commands. В этом каталоге также нужно создать пустой файл __init__.py. Теперь откроем addstaffmember.py и добавим в него немного кода.
Сначала нужно загрузить некоторые модули, которыми мы воспользуемся для реализации команды:
from django.core.management.base import BaseCommand, CommandError
Теперь создадим новый класс Command типа BaseCommand и добавим в него функцию handle, в которой будет хранится логика команды:
class Command(BaseCommand):
def handle(self, *args, **options):
print “hello world”
Сохраните файл. К счастью, Django довольно умен и автоматически регистрирует все команды из каталога commands, которые не начинаются с символа подчеркивания. Поэтому, запустив команду python manage.py, вы должны увидеть и свою команду в списке. Для полноты картины добавим короткую строку с описанием того, что делает команда. Эта строка появится, когда кто-то запустит python manage.py help addstaffmember. Для этого добавьте строку help после определения класса:
class Command(BaseCommand):
help = ‘добавить сотрудника в базу данных’
В текущем виде наша команда не особо полезна. Нам нужно научиться принимать наборы аргументов, которые мы сможем обработать и добавить в базу данных. Сначала определим аргументы, которые мы принимаем, для чего зададим переменную args точно так же, как ранее задавали переменную help. Внутри переменной args мы укажем принимаемые аргументы. Например:
class Command(BaseCommand):
args ‘firstname lastname job’
help = ‘добавить сотрудника в базу данных’
Если теперь запустить python manage.py help addstaffmember, вы увидите строку help и список ожидаемых аргументов команды. Хотя мы определили эти аргументы, их имена не точно соответствуют переменным скрипта. Вместо этого нужно прочесть аргумент по его положению и записать его значение в переменную. Например:
item_firstname = args[0]
item_lastname = args[1]
item_job = args[2]
Мы считали свои данные, и можно добавить их в базу. Для начала загрузим нашу модель:
from company.models import Staff
Теперь можно создать запись Staff, в которую мы передаем данные переменных и затем сохраняем ее в базу данных:
entry = Staff.objects.create(firstname=item_firstname, lastname=item_lastname, job=item_job)
entry.save()
Наша команда готова! Можно проверить ее так:
python manage.py testcommand “Alan” “Cox” “Kernel Programmer”
Когда мы запустим эту команду, наша таблица Staff обновится, и вы должны увидеть ее в своем проекте! Вот полный скрипт команды:
from django.core.management.base import BaseCommand, CommandError
from company.models import Staff
class Command(BaseCommand):
args = ‘firstname lastname job’
help = ‘Adds a staff member to the database.’
def handle(self, *args, **options):
item_firstname = args[0]
item_lastname = args[1]
item_job = args[2]
entry = Staff.objects.create(firstname=item_firstname, lastname=item_lastname, ob=item_job)
entry.save()
[править] Понимание своих моделей
Как и у большинства новичков в Django, в ваших первых проектах будет совсем немного моделей. По мере освоения системы, с ростом проектов от небольших до полноценных приложений, которыми должны будут пользоваться и другие, ваши модели будут расти и расширяться. Вскоре у вас будет огромный список взаимосвязанных моделей, и с изменением дизайна и функциональности будут меняться и ваши модели. В результате вы будете улучшать свои модели шаг за шагом в надежде создать окончательную версию дизайна, чтобы больше не изменять модели, когда проект начнет использоваться.
Перед окончательным релизом вы, вероятно, захотите полностью просмотреть свои модели, чтобы убедиться, что в них нет никаких бессмысленных связей. Подробно рассмотреть такое множество взаимосвязанных моделей сложно. Поэтому полезно иметь схему всех своих моделей и связей между ними. К счастью, сидеть и рисовать ее вручную не придется – ее можно сгенерировать автоматически.
Для этого нужно установить расширения Django (Django Extensions). Это набор полезных дополнений к функциональности manage.py. Для вашего дистрибутива должен быть соответствующий пакет (например, в Ubuntu я установил python-django-extensions). Исходный код можно загрузить напрямую с https://github.com/django-extensions/django-extensions.
Чтобы воспользоваться расширениями, нужно убедиться, что они добавлены как приложение в settings.py вашего проекта в раздел INSTALLED_APPS. Добавьте в INSTALLED_APPS следующее:
django_extensions
Для построения схемы нужно запустить команду, которая сгенерирует схему GraphViz; это специальный язык разметки, используемый для генерации схем. Обычно затем с помощью другой утилиты схема конвертируется в удобный для просмотра вид. И все это можно сделать одной командой!
python manage.py graph_models company -a -g -o my_project.png
Здесь мы выполняем команду graph_models для приложения company и генерируем файл my_project.png с нашей схемой. Пример такой схемы показан на рис. 1.
Django – фантастический каркас для создания мощных web-приложений с возможностями, расширяемостью и удовольствием от работы, сравнимыми со всем этим при написании приложений на Python. В нашей серии мы исследовали множество тем, но многие остались за ее рамками. Рекомендую погрузиться в превосходную документацию на https://docs.djangoproject.com/en – и обязательно задавать вопросы на сайтах http://stackoverflow.com, помечая их тэгом Django. Еще один прекрасный источник помощи – канал #django в IRC-сети Freenode.
Если вы следовали за нами в течение всей серии о Django, спасибо вам за это. Удачи с будущими проектами, и обязательно сообщите мне о своих успехах. Всего доброго! |