Часть четвёртая. Шаблон сайта
Делаем простые шаблоны
Цель: Создание полноценного сайта с простых шаблонов
Задачи:
- Создание простых страниц на HTML
- Изменение ссылок внутри проекта
- Введение динамических и статических элементов страницы
В этой части курса мы научимся выводить полноценные html-страницы. Так как, мы хотим создать шаблон страниц, а не просто одну страницу, мы должны прибегнуть к полноценной вёрстке на Python. Для этого, в папке нашего приложения blog, нужно создать папку templates. Название папки зарезервировано плагином Django, так как Django каждый раз собирает наши файлы и с нуля отрисовывает страницу. При сборке сайта, джанго обращается к папкам и файлам с конкретными названиями.

Папка "blog"
Теперь, в папке templates, нам нужно создать ещё одну папку, которая точно также называется, как и приложение, то есть в нашем случае – blog.
Почему именно так? Дело в том, что Django собирает все папки в единую папку templates. Сейчас у нас одно приложение – blog, но если бы у нас было бы ещё несколько приложений, то в папке templates был бы хаос из файлов. Несмотря на то, что у нас одно приложение, мы будем писать сайт с правилами хорошего тона в программировании.
Теперь в папке blog, создадим файлы home.html и contacts.html

Как мы видим, файлы у нас не пусты.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>
Удалим всё лишнее.
Настроим PyCharm. Нам потребуется плагин для работы с html-файлами. Плагин называется – Emmet.
Переходим в IDE по следующей ветке: File -> Settings

В панели поиска напишем название нашего плагина


Обычно, он установлен по умолча нию и находится во вкладке Editor. Если его у вас нет, нажмите кнопку Install в появляющемся после запроса окне.
Как мы видим, плагин будет реагировать на кнопку “Tab”. Это нам и нужно. Нажимаем ОК и возвращаемся к файлам html.
Введите
!
и нажмите Tab.
Весь текст набрался самостоятельно
Не меняем ничего, кроме двух пунктов.
- 1.Удалим в поле
<title>
слово “Documents” - 2.В теле введём заголовок
<h2>
Результат (contacts.html):
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
</head>
<body>
<h2>Контакты работают иначе</h2>
</body>
</html>
Теперь, чтобы шаблоны были доступны, необходимо в главном файле настройки проекта – settings.py в установленных приложениях (INSTALLED_APPS) ввести наше приложение – blog.
Сделаем тоже самое для главной страницы.
Результат (home.html):
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
</head>
<body>
<h2>Ура! Главная страница поменялась</h2>
</body>
</html>
Переходим к файлу настроек и вписываем туда строку:
blog.apps.BlogConfig
Таким образом, мы вводим приложение blog, сведения о котором хранятся в файле apps и обращаемся к функции BlogConfig.
Результат:
INSTALLED_APPS = [
'blog.apps.BlogConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
Взглянем на файл apps.py в проекте сайта.
from django.apps import AppConfig
class BlogConfig(AppConfig):
name = 'blog'
Остался последний шаг – настроить vievs.py. Сейчас там прописаны функции – HttpResponse, то есть ответы через http. Это неправильно. Сайт будет работать на html вёрстке и нам нужно не выдавать http ответы, а обращаться к html шаблонам. Исправляем:
from django.shortcuts import render
from django.http import HttpResponse
def home(request):
return render(request, 'blog/home.html')
def contacts(request):
return render(request, 'blog/contacts.html')
Обратите внимание на сигналы PyCharm:

Строка с импортом библиотеки HttpResponse стала серой. Это знак того, что мы не использовали в фале программы эту библиотеку. Её можно удалить.
Помимо прочего, появилось зелёные ярлычки слева. Это знак, что мы обращаемся к нашему html-файлу. Если навести на него курсор, отобразиться имя файла, а если кликнуть по нему, мы перейдём в этот файл.

Запускаем сервер и проверяем как всё работает:


Всё работает как надо!
Теперь научимся передавать динамические данные. Это – заготовка под базы данных, которыми мы потом будем пользоваться.
Перейдём в файл views.py.
Написав немного кода, я изменил файл так:
from django.shortcuts import render
news = [
{
'title': 'Первая запись',
'text': 'Много-много текста',
'date': '10 Мая 2020',
'author': 'Валерий'
},
{
'title': 'Вторая запись',
'text': 'Снова много-много текста',
'date': '19 Мая 2020',
'author': 'Егор'
}
]
def home(request):
data = {
'news': news,
'title': 'Главная страница'
}
return render(request, 'blog/home.html', data)
def contacts(request):
return render(request, 'blog/contacts.html')
Построчно разберём что к чему. Создан список news, состоящий из 2 записей. Каждая запись – это словарь. В каждом словаре по 4 элемента. В функции отрисовки главной страницы, я добавил переменную data, которая создаёт словарь news и вызывает в него созданный список новостей. Плюс к этому, в data мы вызывает ещё один объект – заголовок страницы (title). В самом же рендере, мы добавили переменную в конце и вызываем её.
Теперь перейдём в html-файл нашей главной страницы (home.html)
Снова написав не много кода, получаем следующее:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{ title }}</title>
</head>
<body>
{% for post in news %}
<h1>{{ post.title }}</h1>
<p>{{ post.text }}</p>
{% if post.author == 'Валерий' %}
<p>Автор: Админ</p>
{% else %}
<p>Автор: {{ post.author }}</p>
{% endif %}
<p>Дата: {{ post.date }}</p>
{% endfor %}
</body>
</html>
В поле \ мы вызываем нужную нам строку – «Главная страница». В теле мы используем 2 конструкции:
- 1.for
- 2.if
Так как, мы пишем вёрстку на Python в html-файле, конструкции используются при помощи такой конфигурации:
{% %}
Если бы мы писали тот же код, но на чистом питоне, выглядел бы он так:
for post in news:
print('post.title')
print('post.text')
if post.author == 'Валерий':
print('Автор: Админ')
else:
print('Автор: ', post.author)
print('Дата: ', post.data)
Посмотрите основные отличия:
- Отсутствие двоеточий после for и if, но наличие конструкци и endfor и endif
- Добавлена разметка html, то есть <p>, <h2> и т.п.
- Отсутствие кавычек и слова "print"
Запустим сервер и посмотрим на результат:

Подредактируем ещё немного файл views.py. Допустим, нам нужно вывести только заголовок (title), а остаток кода не менять и не выводить все новости (data). В таком случае, сделаем следующую конструкцию:
def contacts(request):
return render(request, 'blog/contacts.html', {'title': 'Страничка про МИИГАиК'})
А в файл contacts.html выглядит теперь так:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{ title }}</title>
</head>
<body>
<h2>Контакты работают иначе</h2>
</body>
</html>
Проверяем:

Теперь давайте сравним 2 файла home.html и contacts.html. Что в них отличае тся?
Единственный блок, который у них отличается – тело, а «шапка» (верхняя часть сайта) и «подвал» (нижняя часть сайта) остаются одинаковыми. Конечно, нам не будет интересно переписывать один и тот же код на каждой странице. Давайте исправим это неудобство.
Создадим рядом с файлами home.html и contacts.html файл main.html и пишем в него следующий код:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{ title }}</title>
</head>
<body>
{% block main_section %}
{% endblock %}
</body>
</html>
То есть, мы можем скопировать весь код с любого из html-файла и в теле сайта записать блочную конструкцию:
{% block main_section %}
{% endblock %}
Перейдём в файл contacts.html и перепишем его таким образом:
{% extends 'blog/main.html' %}
{% block main_section %}
<h2>Контакты работают иначе</h2>
{% endblock main_section %}
То есть, мы обращаемся к файлу blog/main.html и из него берём всё, что было до блока, пишем блок (тело страницы) и забираем всё, что нужно после. Повторяем операцию с файлом home.html.
{% extends 'blog/main.html' %}
{% block main_section %}
{% for post in news %}
<h1>{{ post.title }}</h1>
<p>{{ post.text }}</p>
{% if post.author == 'Валерий' %}
<p>Автор: Админ</p>
{% else %}
<p>Автор: {{ post.author }}</p>
{% endif %}
<p>Дата: {{ post.date }}</p>
{% endfor %}
{% endblock main_section %}
Проверяем и видим тоже самое. Давайте теперь напишем какую-нибудь глобальную фразу в main.html. Например, так:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{ title }}</title>
</head>
<body>
<h1>МИИГАиК - лучший ВУЗ!</h1>
{% block main_section %}
{% endblock %}
</body>
</html>
Проверим что получилось:


Теперь эта фраза нас преследует везде и на каждой странице. Сейчас это изменение можно убрать, так как нам ещё предстоит много работы со станицами.
Last modified 2yr ago