Формы для блога на Django: CreateView, UpdateView и DeleteView

Одна из важных составляющих работы с сайтом либо блогом – добавление специальных форм, с помощью которых можно создавать, редактировать и удалять записи в нем.

Как создать форму для записи в блоге?

Форма – важный, но довольно непростой в плане реализации элемент. В ходе работы с информацией, введенной пользователем, под ударом находится система безопасности (возможны XSS атаки). Одновременно с этим, необходимо создать гибкий обработчик ошибок. Кроме этого, появляется необходимость правильной настройки пользовательского интерфейса. В этом случае можно предотвратить проблемы с формами на уровне UI. Помимо этого, здесь необходимо реализовать успешные перенаправления на требуемую страницу.

Хорошо, что в Django есть встроенные формы, значительно облегчающие процесс разработки. Они предоставляют широкий ассортимент инструментов, с помощью которых возможно создание веб-сайта.

Сперва обновим базовый шаблон для показа прямой ссылки на страницу создания публикации. Код будет выглядеть так: <a href=»{% url ‘post_new’ %}»></a>, где post_new – URL, который будет использоваться в приложении.

Файл templates/base.html будет выглядеть так: 

<!-- templates/base.html -->

{% load static %}

<html>

  <head>

    <title>Django blog</title>

    <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400"

    rel="stylesheet">

    <link href="{% static 'css/base.css' %}" rel="stylesheet">

  </head>

  <body>

    <div>

      <header>

        <div class="nav-left">

          <h1><a href="{% url 'home' %}">Django blog</a></h1>

        </div>

        <div class="nav-right">

          <a href="{% url 'post_new' %}">+ New Blog Post</a>

        </div>

      </header>

      {% block content %}

      {% endblock content %}

    </div>

  </body>

</html>

Теперь добавим обновленный URL-маршрут для страницы добавления публикации post_new. Вверху импортируем еще не созданное представление, называющееся BlogCreateView. Затем прописываем URL-маршрут, с именем post_new, начало которого будет с post/new/. 

# blog/urls.py

from django.urls import path

 

from .views import BlogListView, BlogDetailView, BlogCreateView # new

 

urlpatterns = [

    path('post/new/', BlogCreateView.as_view(), name='post_new'), # new

    path('post/<int:pk>/', BlogDetailView.as_view(), name='post_detail'),

    path('', BlogListView.as_view(), name='home'),

]

Не настолько тяжело, как может показаться на первый взгляд, правда? Аналогичные URL, представления и шаблоны уже знакомы каждому разработчику, который имеет хоть немного опыта работы с Django.

Теперь давайте попробуем создать представление. Для этого вверху импортируем класс представлений, называющийся CreateView и осуществляем его наследование в BlogCreateView

# blog/views.py

from django.views.generic import ListView, DetailView

from django.views.generic.edit import CreateView # новое изменение

 

from .models import Post

 

 

class BlogListView(ListView):

    model = Post

    template_name = 'home.html'

 

 

class BlogDetailView(DetailView):

    model = Post

    template_name = 'post_detail.html'

 

 

class BlogCreateView(CreateView): # новое изменение

    model = Post

    template_name = 'post_new.html'

    fields = ['title', 'author', 'body']

Внутри BlogCreateView делаем указание на Post, а также имя HTML-шаблона post_new.html. Далее поля выбираем напрямую из таблицы, и их задействуем— в этом случае такими полями являются title, author и body.

Далее генерируем HTML-шаблон post_new.html. 

(blog) $ touch templates/post_new.html

Потом добавляем такой HTML-код. 

!-- templates/post_new.html -->

{% extends 'base.html' %}

 

{% block content %}

    <h1>New post</h1>

    <form action="" method="post">{% csrf_token %}

      {{ form.as_p }}

      <input type="submit" value="Save" />

    </form>

{% endblock content %}

Давайте разберемся в том, что означает то, что мы делали ранее.

  1. Сверху приведен базовый шаблон, структура которого и будет дополняться нами.
  2. Применяется HTML тег <form> с методом POST, поскольку в этом случае осуществляется отправка информации. Если мы получаем данные из поля поиска, то тогда, как мы можем помнить, используется GET.
  3. Добавляется токен {% csrf_token %}, с помощью которого Django реализуется защита от межсайтового скриптинга. Он используется для всех форм, которые создаются с помощью нашего фреймворка.
  4. Для показа формы – {{ form.as_p }}, что размещает форму внутрь параграфа. 
  5. Под конец создается кнопка «Save» для сохранения данных, введенных пользователем.

Чтобы просмотреть итог нашей работы, осуществите запуск веб-сервера с помощью команды manage.py runserver и откройте страницу http://127.0.0.1:8000/.

Сделайте клик по ссылке «+ New Blog Post», которая выполнит редирект вас на http://127.0.0.1:8000/post/new/.Формы для блога на Django: CreateView, UpdateView и DeleteView

Попробуйте сделать новую публикацию на блоге, а затем подтвердите свои действия путем клика по кнопке «Save».Формы для блога на Django: CreateView, UpdateView и DeleteView

Ошибка ImproperlyConfigured в Django

О, произошла ошибка. Что же случилось.Формы для блога на Django: CreateView, UpdateView и DeleteView

В Django уведомления о возникших исключениях могут оказаться довольно полезными. Здесь требуется уточнение места, куда будет осуществляться редирект пользователя после того, как будет выполнено подтверждение формы. Давайте отправим его на индивидуальную страницу записи. Это нам позволит посмотреть на созданную публикацию сразу после того, как она будет сделана.

Можно сделать то же самое, что предложил Django и добавить к созданной модели метод get_absolute_url. Так очень хорошо делать. Потому рекомендуется следовать этой практике. Здесь ставится прямой URL для объекта. Следовательно, даже при возможном редактировании структуры URL в будущем, ссылка на объект не изменяется. Простыми словами, вам необходимо использовать методы get_absolute_url() и __str__() для всех имеющихся моделей.

А теперь давайте откроем файл models.py и добавим на второй строчке импорт для reverse и метод get_absolute_url

# blog/models.py

from django.db import models

from django.urls import reverse # Новый импорт

 

 

class Post(models.Model):

    title = models.CharField(max_length=200)

    author = models.ForeignKey(

        'auth.User',

        on_delete=models.CASCADE,

    )

    body = models.TextField()

 

    def __str__(self):

        return self.title

 

    def get_absolute_url(self): # Тут мы создали новый метод

        return reverse('post_detail', args=[str(self.id)])

Reverse – довольно важная функция Django. С ее помощью можно отсылаться к конкретному объекту путем использования URL маршрута. Здесь это post_detail. URL-маршрут таким:

path(‘post/<int:pk>/’, BlogDetailView.as_view(), name=’post_detail’),

Что это значит? Для работы маршрута, помимо всего прочего, необходимо передать аргумент pk либо первичный ключ (ID) объекта. Сложности происходят из-за того, что в Django pk и id могут заменять друг друга, но в официальных руководствах советуют использовать self.id с get_absolute_url. То есть, мы уведомляем Django, что итоговым расположением записи будет post_detail. Это представление будет размещаться по URL-маршруту posts/<int:pk>/. То есть, URL-адрес для первой созданной нами записи будет posts/1.

Давайте сделаем попытку повторного создания записи блога. Откроем адрес http://127.0.0.1:8000/post/new/.Формы для блога на Django: CreateView, UpdateView и DeleteView

После того, как мы нажмем на кнопку «Save», мы будем перенаправлены на индивидуальную страницу созданной записи.Формы для блога на Django: CreateView, UpdateView и DeleteView

После возврата на главную страницу вы увидите, что прошлая запись также имеется в списке. Она была благополучно добавлена в базу. Правда, Django не знал, куда пользователь должен перенаправляться после этого.Формы для блога на Django: CreateView, UpdateView и DeleteView

Естественно, пользователь может открыть админку Django и убрать нежелательные публикации оттуда. Но гораздо лучше идея – добавить формы, с помощью которых пользователь сможет обновлять или убирать публикации непосредственно на сайте блога.

Форма для обновления данных UpdateView в Django

Процесс создания формы для редактирования, с использованием которой люди могут вносить изменения в записи, может показаться знакомым. Мы опять пользуемся встроенные в Django общими представлениями класса UpdateView. С их помощью мы создадим HTML шаблон, url-маршрут и представление.

Сперва давайте добавим ссылку в post_detail.html. Это позволит сделать ссылку на редактирование записи сделать доступной непосредственно со страницы записи, которая добавляется. 

<!-- templates/post_detail.html -->

{% extends 'base.html' %}

 

{% block content %}

  <div class='post-entry'>

    <h2>{{ post.title }}</h2>

    <p>{{ post.body }}</p>

  </div>

 

  <a href='{% url 'post_edit' post.pk %}'>+ Edit Blog Post</a>

{% endblock content %}

Нами была добавлена ссылка, используя HTML-тег <a href>…</a>, и тег языка шаблонов {% url … %}. Внутри нами была уточнена структура url, называемого post_edit. Также был передан запрашиваемый параметр, которым является ключ записи post.pk.

Далее генерируется HTML-шаблон для конкретной страницы редактирования поста, называемой post_edit.html.

(blog) $ touch templates/post_edit.html

Добавляем такой код. 

<!-- templates/post_edit.html -->

{% extends 'base.html' %}

 

{% block content %}

    <h1>Edit post</h1>

    <form action="" method="post">{% csrf_token %}

      {{ form.as_p }}

    <input type="submit" value="Update" />

</form>

{% endblock content %}

Нами снова применяются теги <form></form>. Чтобы сделать процесс более безопасным, необходимо обязательно добавить csrf_token от Django, form.as_p для отображения полей формы и, конечно же, надо создать кнопку «Update» для подтверждения внесенных корректив.

Выводы

Конечно, это не все аспекты работы с формами. Этот процесс включает множество нюансов, которые обязательно нужно рассмотреть отдельно.

ОфисГуру
Adblock
detector