Блог на Django #22: Рендеринг форм в шаблонах

963

После создания формы и представления, а также добавления URL-шаблона не хватает только шаблона для этого представления. Создайте новый файл в папке blog/templates/blog/post/ и назовите его share.html. После этого добавьте следующий код:

{% extends "blog/base.html" %}  
  
{% block title %}Share a post{% endblock %}  
  
{% block content %}  
  {% if sent %}  
    <h1>E-mail successfully sent</h1>  
    <p>  
      "{{ post.title }}" was successfully sent to {{ form.cleaned_data.to }}.  
    </p>  
  {% else %}  
    <h1>Share "{{ post.title }}" by e-mail</h1>  
    <form action="." method="post">  
      {{ form.as_p }}  
      {% csrf_token %}  
      <input type="submit" value="Send e-mail">  
    </form>  
  {% endif %}  
{% endblock %}

Это шаблон для отображения формы или сообщения об успешной отправке. Как можно заметить, создается HTML-элемент form. Отправка его происходит с помощью метода POST:

<form action="." method="post">

Затем включается актуальный экземпляр формы. Django сообщается, что он должен рендерить поля в HTML-абзацах — элементах <p> с помощью метода as_p. Также формы можно отрендерить в виде ненумерованного списка с помощью as_ul или как HTML-таблицу с помощью as_table. Если нужно отрендерить каждое поле, можно перебрать поля как в этом примере:

{% for field in form %}
  <div>
    {{ field.errors }}
    {{ field.label_tag }} {{ field }}
  </div>
{% endfor %}

Ярлык шаблона {% csrf_token %} представляет собой скрытое поле с автоматически генерируемым токеном, который позволяет избежать атак cross-site request forgery (CSRF, «межсайтовая подделка запроса»). Такие атаки представляют собой сайты или программы злоумышленников, выполняющие нежелательные действия за пользователя на сайте. Подробно этом написано по ссылке https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF).

Этот ярлык генерирует скрытое поля, которые выглядит вот так:

<input type='hidden' name='csrfmiddlewaretoken'
value='26JjKo2lcEtYkGoV9z4XmJIEHLXN5LDR' />

По умолчанию Django проверяет CSRF — токен для всех запросов POST. Не забывайте включить ярлык_ csrf_token во все формы, отправляемые с помощью POST.

Отредактируйте шаблон blog/post/detail.html и добавьте следующую ссылку в URL поста, которым будут делиться, после переменной {{ post.body|linebreaks }}:

<p>
  <a href="{% url 'blog:post_share' post.id %}">
    Share this post
  </a>
</p>

URL создаются динамически с помощью ярлыка шаблона {% url %} из Django. Используется пространство имен blog и URL post_share. ID поста передается в качестве параметра для создания абсолютного URL.

Запустите сервер разработки с помощью команды python manage.py runserver и откройте https://127.0.0.1:8000/blog/ в браузере. Нажмите на название любого поста, под ним будет добавленная ссылка:

Python data course

Добавление "поделиться" в пост Django

Кликните на «Share this post». Откроется страница с формой для того, чтобы поделиться этим постом через email:

страница с формой Django

CSS-стили есть в коде примера в static/css/blog.css. После нажатия на SEND E-MAIL форма отправляется и проверяется. Если данные в полях правильные, отобразится сообщение об успехе E-mail successfully sent.

Если данные неверные, форма отрендерится заново с ошибками проверки.

Некоторые современные браузеры не дадут отправлять формы с пустыми или некорректными полями. Это происходит из-за того, что проверка форм браузерами основывается на типах полей и их ограничениях. В этом случае форма не будет отправлена, а браузер отобразит ошибку для некорректных полей.

форма не отправлена, браузер отобразил ошибку

Форма чтобы делиться постами через email готова. Дальше создадим систему комментариев для блога.

Учитесь программировать по книгам, подписывайте на телеграм каналы:

Книги Python разработчика RU / EN

Книги / Data Science / RU-EN

Тест на знание python

Какой будет результат выполнения кода — print(abc) ?
Какой будет результат выполнения кода — print(type(1J)) ?
Как узнать длину списка?
Какие операторы можно использовать со строками?
Верно ли данное утверждение: "В Python есть два типа чисел: целые числа и числа с плавающей точкой"?
Александр
Я создал этот блог в 2018 году, чтобы распространять полезные учебные материалы, документации и уроки на русском. На сайте опубликовано множество статей по основам python и библиотекам, уроков для начинающих и примеров написания программ. Пишу на популярные темы: веб-разработка, работа с базами данных, data sciense и другие...