Декабрь 2016

Этот курс закончился

Cписок курсов

Домашнее задание. Приложение «Гостевая Книга»

25 декабря 2016

Требуется создать приложение «Гостевая книга». Приложение должно поддерживать возможность публикации сообщений, отображения их в хронологическом порядке, вход и регистрацию пользователей с возможностью восстановления и смены пароля. Кроме того, нужно обеспечить интерфейс администратора.

Дополнительные материалы к сайту

Скачайте вот это архив и распакуйте его. Внутри вы найдёте модуль reg_view.py и каталог с шаблонами templates. Описание этих файлов см. ниже.

Модели данных

В этой задаче только одна модель данных: Сообщение (Message). У сообщения должны быть следующие поля:

  • автор (author) — пользователь, который отправил сообщение. Тип поля — ForeignKey от модели django.contrib.auth.models.User. Если мы хотим разрешить оставлять сообщения без регистрации, то это поле может содержать None: задайте полю параметр null=True.
  • тема (subject или subj) — тема сообщения. Тип поля — строка, то есть CharField. Максимальная длина — скажем, 250 знаков.
  • текст (text) — текст сообщения. Ради простоты и безопасности не будем разрешать пользователям вводить теги HTML или другую разметку. Тип поля — TextField.
  • дата публикации (скажем, pub_date) — дата и время публикации сообщения. Тип поля — DateTimeField. Установку даты публикации можно автоматизировать: задайте у этого поля параметр auto_now=True, и в него будет автоматически заноситься дата и время создания сообщения. Сообщения будут сортироваться по этому полю по убыванию (то есть новые сверху).

Обязательно нужно зарегистрировать модель в файле admin.py. Создайте там администативный класс MessageAdmin, отнаследованный от admin.ModelAdmin и воспользуйтесь декоратором @admin.register. В классе MessageAdmin задайте параметры list_display, ordering, а так же любые другие параметры, управляющие отображением админки, какие сочтёте нужными.

Структура адресов

На сайте будут доступны следующие URL:

  • Главная страница (рег. выражение r'^$') — соответствующее представление (view) будет выводить все сообщения, отсортированные по убыванию даты публикации.
  • Адрес /add/ (рег. выражение r'^add/$') — форма публикации нового сообщения. Соответсвующее представление выводит и обрабатывает форму публикации сообщения. В форме два поля: тема сообщения (subj) и текст сообщения (text). Оба поля обязательны. В обычной ситуации представление показывает пустую форму. Если же форма была отправлена на обработку (это можно проверить через свойство request.method, см. про обработку форм ниже), то представление проверяет, все ли поля заполнены. Если да, то представление создаёт новое сообщение, сохраняет его и перенаправляет (см. ниже) пользователя обратно на главную страницу. Если хоть одно поле не заполнено, или заполнено только пробелами, то предствление снова показывает форму, а так же сообщение о том, что надо заполнить поля.
  • Адрес /register/ (рег. выражение r'^register/') — форма регистрации пользователя. К сожалению, приложение django.contrib.auth не содержит готового view для этой цели. Я взял на себя смелость реализовать недостающую функцию — это функция register_new_user в модуле reg_views. Для подключения этого модуля поместите файл reg_views.py из архива в ваше приложение, и добавьте в urls.py следующие строки:
# 1. Импорт функции
from guest_book.reg_views import register_new_user

# 2. Подключение view к адресу
urlpatterns = [
    # ... всё остальное

    url(r'^register/$', register_new_user, name='register'),
]
  • Адреса из приложения django.contrib.auth. Для этого добавьте в urls.py
# 1. Импорт функции include
from django.conf.urls import url, include # include дописано к уже имеющейся строке

#2. Подключение адресов
urlpatterns = [
    # ... всё остальное

    url(r'^', include("django.contrib.auth.urls")),
]
  • Кроме того, ещё должна быть подключена панель администрирования (она подключена по умолчанию, если вы специально её не удаляли).
from django.contrib import admin

urlpatterns = [
    # ... всё остальное
    url(r'^admin/', admin.site.urls),
]

Обработка формы публикации сообщения

Работать с формой можно двумя путями. Во-первых, напрямую, во-вторых, с помощью модуля django.forms. Далее рассмотрена работа с формой напрямую. Переделать форму для использования с модулем django.forms не составит труда.

Форма состоит из двух полей и одной кнопки. Кроме того, поскольку форма отправляется методом POST, необходимо добавить в неё CSRF-токен (это делается с помощью django-тега {% csrf_token %}. Показывает и обрабатывает форму одно и то же представление, как обычно.

Соответственно, представление может запуститься в одной из двух ситуаций:

  1. Пользователь перешёл по ссылке «НАПИСАТЬ» и собирается ввести текст сообщения.
  2. Пользователь нажал «Опубликовать сообщение» в форме, и нужно обработать форму.

Отличить эти ситуации можно по методу запроса. В первом случае, при обычном переходе по ссылке, браузер использует метод по-умолчанию — метод GET. При отправке формы на обработку используется указанный в форме метод — в нашем случае POST. Таким образом, следующий код различит эти ситуации:

def add_message_view(request):
    if request.method == 'POST':
        # Обработка формы
    else:
        # Показ страницы с формой

Значения, введённые пользователем в поля формы при обработке, можно извлечь из словаря request.POST: например, если поле формы называется subj, следующий код достанет это поле из формы в переменную subj_value.

def add_message_view(request):
    if request.method == 'POST':
        if 'subj' in request.POST:
            subj_value = request.POST['subj']
        else:
            subj_value = ""
        #... и т.д.

При обработке формы необходимо проверить корректность введённых данных. Если данные некорректны, следует снова показать страницу с формой, добавив на неё сообщение о том, какие поля и как надо исправить.

Если же форма корректна, нужно обработать её содержимое (сохранить в БД, например), а затем либо отобразить страницу с сообщением об успешной обработке, либо перенаправить пользователя на другую страницу сайта.

Перенаправление пользователя

В протоколе HTTP предусмотрена возможность перенаправления браузера от адреса к адресу. В Django это реализует специальный HTTP Response (ответ HTTP): класс HttpResponseRedirect. Он находится в модуле django.http, не забудьте импортировать перед использованием.

В следующем примере view перенаправляет пользователя на главную страницу сайта:

from django.shortcuts import render
from django.http import HttpResponseRedirect

def process_view(request, data):
    if data and data.is_valid():
        process_data(data)
        return HttpResponseRedirect("/") # Параметр — URL
    else:
        return render(request, "error_bad_data.html", context={"data": data})

Оформление сайта

Чтобы верстать веб-страницы красиво, требуются специфические знания и опыт. Однако есть такая штука, как CSS-фрэймворки. Это готовые таблицы стилей, которые задают вашему сайту некоторое современно выглядещее оформление — пусть и немного однообразное, но симпатичное. Этого бывает достаточно, чтобы сделать прототип сайта, который не стыдно показать, а для проектов, ориентированных на содержание (вроде сайтов-библиотек) этого оформления может быть достаточно в принципе.

Один из таких фрэймворков — W3.CSS.

Сайт http://www.w3schools.com оформлен полностью с помощью этого фрэймворка. Примеры его работы показаны на странице W3.CSS Intro.

Пользоваться им просто. Он включает в себя множество CSS-классов, которые влияют на разные аспекты оформления элементов — цвета, границы, отступы и т.д. В документации на сайте это всё расписано по разделам. В каждом разделе есть примеры использования. Основная идея такая: делаете в HTML-коде элемент (например, <div>), и указываете у него атрибут class. Например, блок с голубым фоном, отсутпами и рамкой:

<div class="w3-blue w3-container w3-border">
    Привет, мир!
</div>

Класс w3-blue задаёт голубой фон и белый текст, w3-container добавляет стандартные оступы, а w3-border добавляет стандартную серую рамку. Вот так классы можно комбинировать.

Существуют и другие фрэймворки - Bootstrap, Skeleton и прочие. Альтернатива фрэймворкам — готовые шаблоны сайтов, которые включают в себя и CSS, и HTML, и даже JavaScript. Например, бесплатные шаблоны на сайте HTML5 UP.

Шаблоны в архиве

В каталоге templates в архиве находятся готовые свёрстанные шаблоны. Они реализованы с помощью W3.CSS. Те, что в подкаталоге registration, относятся к приложению django.contrib.auth — это шаблоны страниц входа на сайт, регистрации пользователя, смены и восстановления пароля, и так далее. Подробнее см. документацию Django.

Остальные шаблоны:

  • base.html — базовый шаблон. В нём находится панель навигации. От этого шаблона отнаследованы все остальные, включая те, что в подкаталоге registration.
  • main.html — шаблон главной страницы. Выводит список сообщений messages. Выделяет сообщения от обычных и анонимных пользователей разным цветом.
  • add.html — шаблон формы публикации нового сообщения.

Вы можете использовать эти шаблоны, переделав их под свои модели и view. Так же вы можете, экспериментируя со стилями W3.CSS, добиться собственного оформления сайта.

Настройка сайта в settings.py

Обязательно внесите в ваш файл settings.py следующие настройки:

  • LOGIN_REDIRECT_URL = "\" — этот параметр задаёт, на какой адрес будет перенаправлен пользователь сразу после входа на сайт

А так же задайте параметры отправки e-mail (вам понадобится отдельно зарегистрировать почтовый ящик для сайта, или использовать существующий). Сайт на хостинге PythonAnywhere будет работать только с GMail. Для GMail-ящика укажите следующие настройки:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'ВАШ-ЛОГИН@gmail.com'
EMAIL_HOST_PASSWORD = 'ВАШ-ПАРОЛЬ-ОТ-ПОЧТЫ'
EMAIL_USE_TLS = True
DEFAULT_FROM_EMAIL = 'ВАШ-ЛОГИН@gmail.com'

Теперь система восстановления пароля будет работать. Если всё же письма не отправляются, проверьте на локальном сервере (python manage.py runserver). Если с локального сервера всё работает, а на PythonAnywhere — нет, обратитесь к справочной информации тут.