При первом вызове form.save() передается аргумент commit=False, потому что новая тема должна быть изменена перед сохранением в базе данных (1) . Атрибуту owner новой темы присваивается текущий пользователь (2). Наконец, мы вызываем save() для только что определенного экземпляра темы (3). Теперь тема содержит все обязательные данные, и ее сохранение пройдет успешно.
Вы сможете добавить сколько угодно новых тем для любого количества разных пользователей. Каждому пользователю будут доступны только его собственные данные, какие бы операции он ни пытался выполнять: просмотр данных, ввод новых или изменение существующих данных.
Упражнения
19-3. Рефакторинг: в views.py есть два места, в которых программа проверяет, что пользователь, связанный с темой, является текущим пользователем. Поместите код этой проверки в функцию с именем check_topic_owner() и вызовите эту функцию при необходимости.
19-4. Защита new_entry: пользователь может попытаться добавить новую запись в журнал другого пользователя, вводя URL-адрес с идентификатором темы, принадлежащей другому пользователю. Чтобы предотвратить подобные атаки, перед сохранением новой записи проверьте, что текущий пользователь является владельцем темы, к которой относится запись.
19-5. Защищенный блог: в проекте Blog примите меры к тому, чтобы каждое сообщение в блоге было связано с конкретным пользователем. Убедитесь в том, что чтение всех сообщений доступно всем пользователям, но только зарегистрированные пользователи могут создавать новые и редактировать существующие сообщения. В представлении, в котором пользователи редактируют сообщения, перед обработкой формы убедитесь в том, что редактируемое сообщение принадлежит именно этому пользователю.
Итоги
В этой главе вы научились использовать формы для создания новых тем и записей, а также редактирования существующих данных. Далее мы перешли к реализации системы учетных записей. Вы предоставили существующим пользователям возможность начинать и завершать сеанс работы с приложением, а также научились использовать класс Django UserCreationForm для создания новых учетных записей.
После создания простой системы аутентификации и регистрации пользователей вы ограничили доступ пользователей к некоторым страницам; для этого использовался декоратор @login_required. Затем данные были связаны с конкретными пользователями при помощи отношения внешнего ключа. Вы также узнали, как выполнить миграцию базы данных, когда миграция требует ввести данные по умолчанию.
В последней части главы вы узнали, как ограничить состав данных, просматриваемых пользователем, с использованием функций представления. Для чтения соответствующих данных использовался метод filter(), а владелец запрашиваемых данных сравнивался с текущим пользователем.
Не всегда бывает сразу понятно, какие данные должны быть доступны всем пользователям, а какие данные следует защищать, но этот навык приходит с практикой. Решения, принятые нами в этой главе для защиты данных пользователей, наглядно показывают, почему при построении проекта желательно работать в команде: если кто-то просматривает код вашего проекта, это повышает вероятность выявления плохо защищенных областей.
К настоящему моменту мы построили полностью функционирующий проект, работающий на локальной машине. В последней главе мы доработаем оформление приложения Learning Log, чтобы оно выглядело более привлекательно. Также проект будет развернут на сервере, чтобы любой пользователь с доступом к Интернету мог зарегистрироваться и создать учетную запись.
20. Оформление и развертывание приложения
Приложение Learning Log уже вполне работоспособно, но оно не имеет стилевого оформления и работает только на локальной машине. В этой главе мы определим для проекта простое, но профессиональное оформление, а затем развернем его на сервере, чтобы любой желающий мог создать учетную запись.
Для стилевого оформления будет использоваться библиотека Bootstrap — набор инструментов для оформления веб-приложений, с которыми они будут выглядеть профессионально на любых современных устройствах, от большого монитора с плоским экраном до смартфона. Для этого мы воспользуемся приложением django-bootstrap3, а вы заодно потренируетесь в использовании приложений, созданных другими разработчиками Django.
Для развертывания Learning Log будет использоваться Heroku — сайт, позволяющий загрузить ваш проект на один из его серверов, чтобы сделать его доступным для любого пользователя с подключением к Интернету. Также мы начнем пользоваться системой контроля версий Git для отслеживания изменений в проекте.
Когда работа с Learning Log будет завершена, вы будете уметь разрабатывать простые веб-приложения, придавать им качественный внешний вид и развертывать их на работающих серверах. Также по мере накопления опыта вы научитесь пользоваться ресурсами с материалами более высокого уровня.
Оформление приложения Learning Log