Шаблоны Django в Python: создание и использование

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

Это руководство начинается с того места, где закончилось создание приложения Django.

Содержание

Введение в шаблоны Django

В предыдущем уроке вы узнали, как вернуть HttpResponse с тегом h1 из представления. Чтобы вернуть полную страницу HTML, вам нужно будет использовать шаблон. Обратите внимание, что можно вернуть полную HTML-страницу, смешав HTML с кодом Python. Однако это непрактично и плохо масштабируется.

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

Шаблонизатор Django создает шаблоны, содержащие переменные, конструкции, теги и фильтры.

Переменные

Переменная заключена в {{ и }}. Например:

Hi {{name}}, welcome back!

В этом шаблоне name является переменной. Если значение переменной имени равно John, шаблонизатор Django преобразует указанный выше шаблон в следующий текст:

Hi John, welcome back!

Если переменная является словарем, вы можете получить доступ к элементам словаря, используя точечную нотацию (dict_name.key).

Предположим, у вас есть словарь person с двумя ключами: name и email:

person = {'name': 'John', 'email': '[email protected]'}

… вы можете получить доступ к значениям ключей имени и электронной почты словаря person в шаблоне следующим образом:

{{ person.name }}
{{ person.email }}

Теги

Теги отвечают за вывод содержимого, обслуживание управляющей структуры if-else, цикла for и получение данных из базы данных.

Теги окружены {% и %}. Например:

{% csrf_token %}

В этом примере тег csrf_token генерирует токен для предотвращения CSRF-атак.

Некоторые теги, такие как if-else и for-loop, требуют начальных и конечных тегов. Например:

{% if user.is_authenticated %}
Hi {{user.username}} 
{% endif %}

Фильтры

Фильтры преобразуют содержимое переменных и аргументов тегов. Например, чтобы сделать каждое слово в строке заглавным, используйте фильтр заголовка следующим образом:

{{ name | title }}

Если значение переменной имени равно john doe, то фильтр заголовка преобразует его в следующее:

John Doe

Некоторые фильтры принимают аргумент. Например, чтобы отформатировать дату переменной join_date в формате Ymd, используйте следующий фильтр:

{{ joined_date | date: "Y-m-d" }}

Комментарии

Комментарии будут выглядеть так:

{# This is a comment in the template #}

Шаблонизатор Django не отображает текст внутри блоков комментариев.

Примеры шаблонов Django

  • Сначала создайте новый каталог под названием templates внутри каталога блога:
mkdir templates
  • Во-вторых, создайте каталог блога внутри каталога шаблонов:
cd templates
mkdir blog

Обратите внимание, что каталог внутри каталога templates должен иметь то же имя, что и имя приложения. В этом примере каталог blog имеет то же имя, что и приложение blog проекта Django.

  • В-третьих, внутри каталога templates/blog создайте два файла шаблонов home.html и about.html со следующим содержимым.

Файл home.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Home</title>
</head>
<body>
    <h1>Home</h1>
</body>
</html>

Файл about.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>About</title>
</head>
<body>
    <h1>About</h1>
</body>
</html>

Важно отметить, что вам следует добавить приложение блога в список INSTALLED_APPS в файле settings.py, чтобы шаблоны заработали. Обычно вы делаете это сразу после создания нового приложения Django.

INSTALLED_APPS = [
    # ...
    'blog.apps.BlogConfig',
]
  • В-четвертых, откройте файл views.py и измените функции представления home() и about() на следующие:
from django.shortcuts import render


def home(request):
    return render(request, 'blog/home.html')


def about(request):
    return render(request, 'blog/about.html')

В этом файле views.py мы импортируем функцию render() из django.shortcuts.

Функция render() принимает объект HttpRequest и путь к шаблону. Она визуализирует шаблон и возвращает объект HttpResponse.

  • В-пятых, запустите сервер разработки Django:
python manage.py runserver

Наконец, откройте URL http://127.0.0.1:8000/ и URL http://127.0.0.1:8000/about/, вы увидите полные HTML-страницы, которые взяты из шаблонов home.html и about.html.

Передача переменных в шаблон

Мы создадим фиктивные данные записи блога и передадим их в шаблон home.html. Позже вы узнаете, как получить данные записи из базы данных.

Файл views.py будет выглядеть так:

from django.shortcuts import render

posts = [
    {
        'title': 'Beautiful is better than ugly',
        'author': 'John Doe',
        'content': 'Beautiful is better than ugly',
        'published_at': 'October 1, 2022'
    },
    {
        'title': 'Explicit is better than implicit',
        'author': 'Jane Doe',
        'content': 'Explicit is better than implicit',
        'published_at': 'October 1, 2022'
    }
]


def home(request):
    context = {
        'posts': posts
    }
    return render(request, 'blog/home.html', context)


def about(request):
    return render(request, 'blog/about.html')

Как это работает.

  • Сначала создайте новый список (posts), в котором будут храниться фиктивные данные постов.
  • Во-вторых, определите новый словарь context внутри функции home() с ключевыми постами и передайте его функции render() в качестве третьего аргумента.

Внутри шаблона home.html вы можете получить доступ к данным записи через переменную posts.

Следующий шаблон home.html, отображающий сообщения:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<title>Blog</title>
</head>
<body>  
	{% for post in posts %}
		<h2>{{ post.title }}</h2>
		<small>Published on {{ post.published_at }} by {{ post.author}}</small>
		<p>{{ post.content }}</p>
	{% endfor %}
</body>
</html>

Как это работает.

  • Сначала используйте цикл for для итерации по переменной posts. Цикл for заканчивается endfor. И for, и endfor окружены {% и %}.
  • Во-вторых, поместите значение каждого элемента в словарь, используя точечную нотацию(.).

Если вы сохраните home.html и откроете URL-адрес http://127.0.0.1:8000/, вы увидите данные поста, отображаемые на странице.

Помимо цикла for, вы можете использовать другой условный оператор, например if-else. Например:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<title>{% if title %} {{title}} {% else %} Blog {% endif %}</title>
</head>
<body>
	{% for post in posts %}
		<h2>{{ post.title }}</h2>
		<small>Published on {{ post.published_at }} by {{ post.author}}</small>
		<p>{{ post.content }}</p>
	{% endfor %}
</body>
</html>

В этом примере используется оператор if-else для отображения переменной title, если она доступна, или Blog в противном случае.

Чтобы передать переменную title в шаблон home.html, вы добавляете новую запись в контекстный словарь с ключом title в функции home() следующим образом:

def home(request):
    context = {
        'posts': posts,
        'title': 'Zen of Python'
    }
    return render(request, 'blog/home.html', context)

Если вы обновите домашний URL http://127.0.0.1:8000/, вы увидите новый заголовок.

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

Создание базового шаблона

Сначала создайте новый каталог шаблонов в каталоге проекта (не в приложении блога):

├── blog
├── db.sqlite3
├── django_project
├── manage.py
├── templates
└── users

Далее добавьте каталог шаблонов в параметр TEMPLATES в файле settings.py проекта:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates' ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

Обратите внимание, что BASE_DIR — это объект Path, который поступает из встроенного модуля pathlib. Косая черта / — это оператор, который объединяет объект BASE_DIR со строкой ‘templates’. Эта функция в Python называется перегрузкой операторов.

Затем создайте base.html в каталоге шаблонов со следующим кодом:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>{% if title %} {{title}} {% else %} Blog {% endif %}</title>
    </head>
    <body>
        {% block content %}
        {% endblock %}
    </body>
</html>

Base.html служит базовым шаблоном для других шаблонов. Имя базового шаблона может быть любым, например main.html.

После этого измените шаблон home.html внутри каталога templates/blog следующим образом:

{% extends 'base.html' %}

{% block content %}
        <h1>My Posts</h1>
	{% for post in posts%}
	<h2>{{ post.title }}</h2>
	<small>Published on {{ post.published_at }} by {{ post.author}}</small>
	<p>{{ post.content }}</p>
	{% endfor%}
{% endblock %}

Шаблон home.html расширяет шаблон base.html с помощью тега extends. Шаблон home.html имеет свой раздел для блока контента.

Также измените шаблон about.html, который расширяет шаблон base.html:

{% extends 'base.html' %}

{% block content %}
<h1>About</h1>
{% endblock content %}

Наконец, перезапустите сервер разработки Django и откройте URL http://127.0.0.1:8000/, и вы увидите изменения.

Настройка статических файлов

Статические файлы — это CSS, JavaScript и файлы изображений, которые вы используете в шаблонах. Чтобы использовать статические файлы в шаблонах, выполните следующие действия:

  • Сначала создайте статический каталог внутри каталога проекта:
mkdir static

Каталог проекта будет выглядеть так:

├── blog
├── db.sqlite3
├── manage.py
├── mysite
├── static
└── templates
  • Во-вторых, задайте STATICFILES_DIRS в settings.py после файла STATIC_URL, чтобы Django мог найти статические файлы в статическом каталоге:
STATIC_URL = 'static/'
STATICFILES_DIRS = [BASE_DIR / 'static']
  • В-третьих, создайте три каталога js, css и images внутри статического каталога:
├── static
|  ├── css
|  ├── images
|  └── js
  • В-четвертых, создайте style.css внутри каталога CSS со следующим содержимым.
h1{
	color:#0052EA
}

form {
	max-width: 400px;
}
label, input, textarea, select{
	display:block;
	width:100%;
}

input[type="submit"]{
	display:inline-block;
	width:auto;
}

.errorlist {
	padding:0;
	margin:0;
}
.errorlist li{
	color:red;
	list-style:none;
}

.alert{
	padding:0.5rem;	
}

.alert-success{
	background-color: #dfd
}
.alert-error{
	background-color:#ba2121;
	color:#fff;
}

Обратите внимание, что мы используем только некоторые простые правила CSS, чтобы сделать руководства более простыми для понимания. Наш основной фокус — Django, а не CSS или JavaScript.

  • В-пятых, создайте app.js внутри каталога js со следующим кодом:
setTimeout(() => {
  alert('Welcome to my site!');
}, 3000);

Этот код показывает предупреждение после загрузки страницы в течение 3 секунд.

  • В-шестых, отредактируйте шаблон base.html, чтобы загрузить файлы style.css и app.js:
{%load static %}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="{% static 'css/style.css' %}" />
    <script src="{% static 'js/app.js' %}" defer></script>
    <title>My Site</title>
  </head>
  <body>
    {%block content%} 
    {%endblock content%}
  </body>
</html>
  • В-седьмых, перезапустите сервер разработки Django, откройте URL-адрес http://127.0.0.1:8000/, и вы увидите, что цвет заголовка меняется в соответствии с правилом CSS.

Кроме того, примерно через 3 секунды вы увидите предупреждение, поскольку в app.js выполняется код JavaScript:

django начать проект - js

Похожие посты
Добавить комментарий

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