# Формы и наследуемые шаблоны
---
## Формы
----
Для ввода данных Django предоставляет формы — объекты, "умеющие" выводить на страницу веб-формы с необходимыми элементами управления и проверять занесенные в них данные на корректность.
----
становим отладочный веб-сервер. Создадим в пакете приложения bboard модуль forms.py, в который занесем слудующий код
```
from django.forms import ModelForm
from .models import Bb
class BbForm (ModelForm):
class Meta:
model = Bb
fields = ('title', 'content', 'price', 'rubric')
```
----
Контроллер-класс будет носить имя 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. Базовый класс "знает", как создать форму, вывести на экран страницу с применением указанного шаблона, получить занесенные в форму данные, проверить их, сохранить в новой записи модели и перенаправить пользователя в случае успеха на заданный интернет-адрес.
----
* template_name — путь к файлу шаблона, создающего страницу с формой;
* form_class — ссылка на класс формы, связанной с моделью;
* success_url — интернет-адрес для перенаправления после успешного сохранения данных (в нашем случае это адрес главной страницы).
----
Займемся шаблоном 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>
```
----
Добавим в модуль urls.py пакета приложения маршрут, указывающий на контроллер CreateView:
```
...
from .views import index, by_rubric, BbCreateView
urlpatterns = [
path('add/', BbCreateView.as_view(), name='add'),
...
]
```
----
Не забудем создать в панели навигации всех страниц гиперссылку на страницу добавления объявления:
`<a href="{% url 'add' %}">Добавить</a>`
----

----
Откроем модель views, ру и внесем следующие правки в код класса BbCreateView:
```
...
from django.urls import reverse_lazy
class BbCreateView(CreateView):
...
success_url = reverse_lazy('index')
...
```
----
Функция reverse lazy из модуля django.urls принимает имя маршрута и значения всех входящих в маршрут URL-параметров (если они там есть). Результатом станет готовый интернет-адрес.
---
## Наследуемые шаблоны
----
Создадим базовый шаблон со следующими блоками:
* title — будет помещаться в теге `<title>` и служить для создания уникального названия для каждой страницы;
* content— будет использоваться для размещения уникального содержимогостраниц.
----
Создадим в папке templates папку layout. Сохраним в ней наш базовый шаблон basic.html
```
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Главная{% endblock %} :: Доска объявлений</title>
</head>
<body>
<header>
<h1>Объявления</h1>
</header>
<nav>
<a href="{% url 'index' %}">Главная</a>
<a href="{% url 'add' %}">Добавить</а>
{% for rubric in rubrics %}
<a href="{% url 'by_rubric' rubric.pk %}">
{{ rubric.name }}</a>
{% endfor %}
</nav>
<section>
{% block content %}
{% endblock %}
</section>
</body>
</html>
```
----
бъявленный в базовом шаблоне блок может быть пустым:
```
{% block content %}
{% endblock %}
```
или иметь какое-либо изначальное содержимое:
```{% block title %}Главная{% endblock %}```
----
Сделаем шаблон bboard\index.html производным от шаблона layout\basic.html.
```
{% extends "layout/basic.html" %}
{% block content %}
{% for bb in bbs %}
<div>
<h2>{{ bb.title }}</h2>
<p>{{ bb.content }}</p>
<p><a href="(% url 'by_rubric' bb.rubric.pk %}">
{{ bb.rubric.name }}</a></p>
<p>{{ bb.published|date:"d.m.Y H:i:s" }}</p>
</div>
{% endfor %}
{% endblock %}
```
----
В самом начале кода любого производного шаблона ставится тег шаблонизатора extends, в котором указывается путь к базовому шаблону. Далее следуют объявления блоков, обозначаемые теми же тегами block и endblock, в которых записывается их содержимое.
----
Аналогично исправим шаблоны bboard\by_rubric.html
```
{% extends "layout/basic.html" %}
{% block title %}{{ current_rubric.name }}{% endblock %}
{% block content %}
<H2>Рубрика: {{ current_rubric.name }}</H2>
{% for bb in bbs %}
<div>
<h2>{{ bb.title }}</h2>
<p>{{ bb.content }}</p>
<p>{{ bb.published|date:"d.m.Y H:i:s" }}</p>
</div>
{% endfor %}
{% endblock %}
```
----
и bboard\create.html
```
{% extends "layout/basic.html" %}
{% block title %}Добавление объявления {% endblock %}
{% block content %}
<h2>Добавление объявления</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Добавить">
</form>
{% endblock %}
```
----
Применим таблицу стилей style.css
```
header h1 {
font-size: 4 Opt;
text-transform: uppercase;
text-align: center;
background: url("bg.jpg") left / auto 100% no-repeat;
}
nav {
font-size: 16pt;
width: 15Opx;
float: left;
}
nav a {
display: block;
margin: lOpx Opx;
}
section {
margin-left: 15%;
}
```
----
Файлы, содержимое которых не обрабатывается программно, а пересылается клиенту как есть, в терминологии Django носят название статических. К таким файлам относятся, например, таблицы стилей и графические изображения, помещаемые на страницы.
----
Остановим отладочный веб-сервер. Создадим в папке пакета приложения bboard папку static, а в ней— вложенную папку bboard. В последней сохраним файлы style.css и bg.jpg (можно использовать любое подходящее изображение, загруженное из Интернета).
----
Откроем базовый шаблон layout\basic.html и вставим в него следующий код:
```
{% load static %}
<!DOCTYPE html>
<html>
<head>
...
<link rel="stylesheet" type="text/css" href="{% static 'bboard/style.css' %}">
</head>
...
</html>
```
----
Тег шаблонизатора load загружает указанный в нем модуль расширения, содержащий дополнительные теги и фильтры. В нашем случае выполняется загрузка модуля static, который содержит теги для вставки ссылок на статические файлы.
----

---
## Задания
----
* Создать формы для заполнения категорий и продавцов (2 задача предыдущей презентации)
* Создать и подключить футер сайта (в нем указать контактную информацию)
{"metaMigratedAt":"2023-06-16T12:06:27.279Z","metaMigratedFrom":"Content","title":"Формы и наследуемые шаблоны","breaks":true,"contributors":"[{\"id\":\"0d39d5a3-691d-488c-8f1e-1a0fb0be4f13\",\"add\":8054,\"del\":673}]"}