LXF167:Добавлять формы
|
|
|
Каркас для web-приложений Добавим функциональности
Содержание |
Django: Данные и формы
Во второй части серии Джоно Бэкон показывает, как заранее загрузить в проект данные и дать пользователям внести свой вклад с помощью форм. [[Файл: |100px|left|thumb|Наш эксперт Джоно Бэкон – менеджер сообщества Ubuntu, автор книги «Искусство сообщества» и основатель ежегодного саммита руководителей сообщества. ]]
В LXF165/166 я написал введение в Django, и оказалось, что многим из вас, наших дорогих читателей, он понравился, и вы хотите узнать о нем больше. Поэтому я рад сообщить, что в нашей серии будут еще три прекрасных статьи. По окончании серии у вас будет все необходимое, чтобы написать полноценное web-приложение Django, которое изумит ваших друзей.
В первой части серии я показал, как создать простое приложение для управления ломбардом. Для этого мы создали проект Django, создали новое приложение в этом проекте, создали модель, активировали интерфейс администратора, чтобы добавить немного данных, и затем создали шаблон и представление для отображения списка результатов. Затем мы создали вид для отображения подробной информации каждого предмета, который хранится в ломбарде. В итоге получилось простое приложение, демонстрирующее основные возможности Django.
В этой части на основе предыдущей работы мы исследуем, как предварительно загрузить в проект данные и создать и применить формы, чтобы пользователи могли добавлять информацию в базу данных.
Предзагрузка проекта данными
Одна из самых приятных черт Django – автоматизированный интерфейс администратора. В других фреймворках обычно приходится создавать его вручную, на что уходит много времени и кода. В Django вы получаете его даром, и с ним очень удобно добавлять в базу новые данные, удалять записи и выполнять другие действия.
Во многих проектах Django удобно автоматически загрузить в проект данные заранее. В нашем примере с ломбардом у нас есть таблица Category. Если бы мы удалили базу данных и снова создали ее, пришлось бы снова добавлять все категории. В идеальном случае хорошо иметь набор категорий по умолчанию, который будет автоматически создаваться при создании базы данных. Для этого нужно создать кое-какие приспособления – фикстуры [fixtures].
Фикстура – это просто готовая запись, добавляемая в базу данных. Когда мы создадим фикстуры, Django автоматически импортирует их при создании новой базы данных. Вот мы их и понаделаем.
На это есть разные способы, но я покажу два простых подхода. Первый – воспользоваться YAML, простым форматом сериализации. Для начала создадим каталог fixtures в приложении Django (в данном случае, в каталоге inventory). Django ищет каталог fixtures в каждом приложении и автоматически загружает найденные фикстуры при создании базы данных.
Создадим файл initial_data.yaml в каталоге fixtures и добавим в него следующие строки:
- model: inventory.category
pk: 1
fields:
name: Watches
- model: inventory.category
pk: 2
fields:
name: Electronics
- model: inventory.category
pk: 3
fields:
name: Instruments
- model: inventory.category
pk: 4
fields:
name: Memorabilia
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
Здесь мы добавили четыре записи в таблицу Category. Для каждого блока мы указываем имя модели (таблица Category внутри приложения inventory). Затем в поле pk мы указываем первичный ключ для каждого блока. Он должен быть уникальным числом. Обычно мы просто начинаем с 1 и увеличиваем его на единицу с каждым блоком. Наконец, мы указываем каждое поле в текущей модели блока (Category) и значение для этого поля. Поскольку наша модель Category имеет всего одно поле (name), это довольно просто; мы просто указываем его значение (например, Watches [Наручные часы]).
Чтобы загрузить фикстуры, просто удалите базу данных, удалив файл pawnstore.db в корневом каталоге проекта и выполнив команду
python manage.py syncdb
При генерации базы данных вы должны увидеть следующую строку:
Installed 4 object(s) from 1 fixture(s)
Она говорит о том, что наши четыре фикстуры были загружены в один файл fixture. Хотя этот подход создания фикстур удобен, он бывает скучным и приводит к ошибкам. Часть проблемы в том, что можно неверно указать первичные ключи, и для моделей с большим количеством полей на создание каждой фикстуры уходит больше времени. Другой подход – добавлять наши данные через интерфейс администратора и экспортировать фикстуры.
Чтобы применить этот подход, сначала удалите базу данных и создайте ее снова, чтобы у нас была свежая база данных. Теперь добавьте данные фикстур через интерфейс администратора. Добавляйте только те данные, которые нужно загрузить заранее, так как все, что вы добавите, экспортируется в фикстуры. Когда вы покончите с этим, сконвертируйте содержимое базы данных в файл YAML, запустив команду:
python manage.py dumpdata inventory format yaml > initial_data.yaml
Эта команда берет все данные из приложения inventory и записывает их в файл initial_data.yaml. Когда команда отработает, можете загрузить файл и посмотреть на сгенерированные данные. Затем просто поместите его в каталог inventory/fixtures, и он будет импортирован при следующем запуске команды python manage.py syncdb.
Добавляем данные через формы
Пока в наших приключениях с Django мы добавляли данные в базу только через интерфейс администратора. Это не самый удобный способ, да к тому же позволенный только администратору. Если вы хотите, чтобы информацию могли добавлять несколько пользователей, или хотите изменить способ добавления информации в базу данных, нужно создать форму.
Для новичков в web-программировании скажу, что формы – это интерактивные элементы управления, через которые можно добавлять информацию на сайт. Например, в почтовом клиенте (скажем, в Google Mail) форма применяется в окне создания письма, где вводятся получатель, тема и сообщение. Эти элементы управления вместе с кнопками Send/Cancel/Save Draft (Отправить/Отмена/Сохранить черновик) представляют собой форму.
К счастью, создавать формы в Django довольно просто. Рассмотрим пример добавления формы для добавления нового предмета в ломбард.
Первым делом добавьте в файл urls.py строку, которая будет соответствовать адресу добавления нового предмета. Откройте urls.py и вставьте в него следующую строку:
url(r’^newitem/$’, ‘inventory.views.newitem’, name=”newitem”),
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
В этой строке мы связываем адрес http://127.0.0.1:8000/newitem/ с представлением newitem. Мы создадим его немного позже. Возможно, вы также заметили, что name=“newitem” есть только в этой строке. Благодаря этому атрибуту, позже мы сможем ссылаться на этот адрес по имени newitem. Тогда, если мы решим изменить адрес, шаблоны менять не придется.
Адрес задан, теперь создадим форму. Ветераны web-разработки сейчас подумали, что мы напишем форму на HTML. К счастью, в Django есть прекрасный способ избежать этой работы.
Одна из функций Django – ModelForms. Если вкратце, с ModelForms можно указать модель, куда нужно добавить данные (например, нашу модель Item), и Django создаст форму на основе типов полей. Например, в нашей модели Item поле Category ссылается на элемент модели Category, а ModelForm автоматически добавит различные категории в выпадающий список. Мы также задаем тип поля Name в CharField, которое будет добавлено в виде однострочного текстового поля. Затем мы задаем поле Description с типом TextField, оно будет добавлено в виде текстового поля большего размера.
Чтобы воспользоваться ModelForms, определим нашу новую форму. Для этого создайте новый файл forms.py в приложении inventory и добавьте в него следующий код:
from django.forms import ModelForm
from inventory.models import Item
class NewItemForm(ModelForm):
class Meta:
model = Item
В этом файле мы сначала импортируем модуль ModelForm, а затем импортируем нашу модель Item из приложения inventory. Затем создаем класс новой формы NewItemForm типа ModelForm. Мы будем создавать свой класс для каждой формы, которую нужно создать в проекте Django.
Затем мы создаем класс Meta как часть нашей формы и указываем, что воспользуемся моделью Item. Это означает, что при дальнейшем обращении к NewItemForm в нашем проекте мы будем обращаться к форме ModelForm, сгенерированной из нашей модели Item.
Создаем представление
Теперь создадим представление, которое будет загружено при открытии адреса http://127.0.0.1:8000/newitem/. Откройте файл views.py и обновите строку django.shortcuts, чтобы заодно импортировать модуль redirect:
from django.shortcuts import render_to_response, redirect
Мы будем использовать этот модуль, чтобы произвести перенаправление на другую страницу (нашу главную) после обработки формы и добавления содержимого в базу данных.
Теперь добавим следующую строку в начало файла:
from django.template import RequestContext
Здесь мы сначала импортируем RequestContext, это новый способ обработки нашего представления. Более подробно об этом позже. Теперь добавим весь код представления:
def newitem(request):
form = NewItemForm(request.POST or None)
if form.is_valid():
cmodel = form.save()
cmodel.save()
return redirect(index)
return render_to_response(‘inventory/newitem.html’, {‘item_form’: form}, context_instance=RequestContext(request))
Пройдемся по каждой строке этого представления. Сначала идет такая:
form = NewItemForm(request.POST or None)
Здесь мы создаем новый экземпляр ModelForm. Мы передадим его нашему шаблону позже. Затем мы проверяем, была ли форма проверена (когда пользователь отправил данные).
if form.is_valid():
Если форма была отправлена, мы создаем объект из данных формы и сохраняем его в базу данных:
cmodel = form.save()
cmodel.save()
Теперь объект сохранен в базе данных. Мы перенаправляем пользователя на главную страницу:
return redirect(index)
Если форма не была отправлена и проверена (и, следовательно, form.is_valid() не равно True), мы с помощью метода render_to_response() затем загружаем шаблон из формы и передаем его нашему объекту формы:
return render_to_response(‘inventory/newitem.html’, {‘item_form’: form}, context_instance=RequestContext(request))
В конце строки вы видите особый фрагмент context_instance =RequestContext(request). Одно из преимуществ RequestContext в том, что он предоставляет защиту от атак методом подделки межсетевых запросов [cross-site request forgery], также известных как атака в один клик или захват сессии [session riding]. Добавив к нашему шаблону токен CSRF, Django поможет защитить ваше приложение от подобных атак.
Теперь представление готово, и пора создать шаблон для обработки формы. В каталоге pawnstore/templates/inventory создайте файл newitem.html и добавьте в него следующий код:
Add New Item
<form action=”{% url newitem %}” method=”post”>{% csrf_token %}
<input type=”submit” value=”Save” />
</form>
В этом файле мы создаем тэг <form> и передаем код шаблона, который будет для вас новым:
<form action=”{% url newitem %}” method=”post”>
Синтаксис { % url newitem %} – это короткая ссылка на строку newitem в файле urls.py. Вы помните, что в этой строке мы указали имя name=“newitem”; ну, а теперь мы на него сослались. Как я отметил, для защиты от атак нам нужен токен CSRF, и теперь мы его добавим:
{% csrf_token %}
Затем мы добавляем саму главную форму: