Формы, связанные с моделями, контроллеры-классы

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

В качестве примера создадим форму, предназначенную для ввода объявлений и связанную с созданной ранее моделью Bb. Назовем новый класс BbForm.

Если запущен отладочный веб-сервер, его необходимо остановить. Далее в приложении bboard создадим модуль forms.py со следующим кодом:

from .models import Bb
class BbForm(modelForm):
    class Meta:
        model = Bb
        fields = ('title', 'content', 'price', 'rubric')

Класс формы, связанной с моделью, является производным от ModelForm (модуль django.forms). Для настроек параметров формы используется вложенный класс Meta: связанная модель (атрибут model) и набор полей, которые будут отображаться в форме (атрибут fields).

Контроллеры-классы

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

В качестве примера создадим новый контроллер класс BbCreateView (объявим в модуле views.py). Добавим в файл следующий код:

from django.views.generic.edit import CreateView
from .forms import BbForm
class BbCreateView(CreateView):
    template_name = 'bboard/create.html'
    form_class = BbForm
    success_url = ' /bboard/'
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context[' rubrics'] = Rubric.objects.all()
        return context

Новый контроллер класс является производным от класса CreateView (модуль django.views.generic.edit). Базовый класс способен выполнять основные операции – создание формы, вывод указанного шаблона, перенаправление пользователя после завершения операции, а также получение, проверку и корректное сохранение введенных данных.

Атрибуты объявленного класса содержат:

— form_class – содержит ссылку на класс формы, который связан с моделью;

— template_name – информация о пути к файлу шаблона для создания страницы с формой;

— success_url – позволяет указать страницу для автоматического перенаправления пользователя после успешного сохранения данных.

Поскольку в нашем проекте на всех страница сайта должен выводиться список рубрик, переопределим метод get_context_data(), который формирует контекст шаблона. Это позволяет добавить в возвращаемый результат список рубрик.

Код шаблона bboard\create.html:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Добавление объявления | Доска объявлений</title>
    </head>
    <body
        <h1>Добавления объявления</h1>
        <div>
            <a href="{% url 'index' %}">Главная</a>
            {% for rubric in rubrics %}
            <a href="{%  url 'by_rubric' rubric.pk  %}">
            {{ rubric.name }}</a>
            {% endfor %}
        </div>
        <form method=''post>
            {% csrf_token %}
            {{ form.as_p }}
            <input type="submit" value="Добавить">
        </form>
    </body>
</html>

Стоит отметить следующее:

— для хранения формы в контексте шаблона используется переменная form, за создание которой отвечает контроллер-класс;

— элементы формы, расположенные на отдельных абзацах, выводятся при помощи метода as_p() класса формы;

— используемый метод as_p() генерирует только код, отвечающий за формирование элементов управления. Теги <input> и <form> пользователь создает самостоятельно.

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

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

Далее необходимо добавить в urls.py пакета приложения маршрут, который свяжет адрес с контроллером CreateView:

. . .
from .views import index, by_rubric, BbCreateView
urlpatterns = [
    path('add/', BbCreateView.as_view(), name='add'),
    . . .
]

Теперь в вызов функции path() автоматически подставляются данные, полученные от метода as_view() контроллера-класса.

Для удобства также добавим в панель навигации, которая отображается на всех страницах, ссылку на страницу добавления нового объявления:

<a href="{% url 'add' %}">Добавить</a>

Теперь можно запустить отладочный сервер и проверить работу новой формы. После заполнения полей и нажатия кнопки Добавить новое объявление будет сохранено и отобразится на главной странице.

При объявлении класса BbCreateView ранее мы явно указали адрес перенаправления (через атрибут success_url). Предпочтительнее использовать обратное разрешение. Изменим код класса BbCreateView в views.py:

from django.urls import reverse_lazy
class BbCreateView(CreateView):
    . . .
    success_url = reverse_lazy('index')
    . . .

Функция reverse_lazy (модуль django.url) получает имя маршрута и URL-параметры, если они используются. В качестве результата возвращается готовый интернет-адрес.   

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: