Инструменты пользователя

Инструменты сайта


шаблоны

Шаблоны

Пример создания простого шаблона

В директории нашего приложения portal, создаем поддиректорию templates, в которой в свою очередь создаем поддиректорию portal. Структура директорий принимает такой вид

C:.                 
├───core_dj         
│   └───__pycache__ 
└───portal          
    ├───migrations  
    ├───templates   
    │   └───portal  
    └───__pycache__ 

по пути core_dj/portal/templates/portal создадим два файла:

  • home.html
  • about.html

Отредактируем файл home.html, с файлом about.html поступим аналогичным образом

home.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
   <h1>Portal Home Page</h1>
</body>
</html>

Далее, идем по пути core_dj/portal/apps.py

apps.py
from django.apps import AppConfig
 
 
class PortalConfig(AppConfig):
    name = 'portal'

И копируем оттуда имя класса, в моем случае это – PortalConfig, затем скопированное имя класса вставляем в список блока INSTALLED_APPS файла core_dj/core_dj/settings.py, после чего, блок принимает такой вид:

settings.py
INSTALLED_APPS = [
    'portal.apps.PortalConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Изменим функции в файле core_dj/portal/views.py

views.py
from django.shortcuts import render
# from django.http import HttpResponse
 
def home(request):
    # return HttpResponse('<h1>Portal Home page</h1>')
    return render(request, 'portal/home.html')
 
def about(request):
    # return HttpResponse('<h1>Portal About</h1>')
    return render(request, 'portal/about.html')

Запускаем веб сервер

python manage.py runserver

Создание публикации

Теперь добавим немного контента на наш портал. Создадим список с публикациями. Поместим его меду импортом модулей и функциями в файле core_dj\portal\views.py. А в функцию home, добавим словарь, содержащий список с публикациями, который был создан выше.

core_dj\portal\views.py
from django.shortcuts import render
 
posts = [
    {
        'author': 'Nevvad',
        'title': 'First portal content',
        'content': 'The fear of death follows from the fear of life. A man who lives fully is prepared to die at any time. - Mark Twain',
        'date_posted': '29 january 2020'
    },
    {
        'author': 'John Doe',
        'title': 'Second portal content',
        'content': 'The truth must be served like a coat, and not thrown in the face like a wet towel. - Mark Twain.',
        'date_posted': '29 january 2020'
    },
]
 
def home(request):
    context = {
        'posts': posts
    }
    return render(request, 'portal/home.html', context)
 
def about(request):
    return render(request, 'portal/about.html')

Теперь, отредактируем шаблон страницы главной страницы home

Конструкция из двух открывающий и двух закрывающих скобок

{{ post.title }}

выводит значение переменной полученной из файла core_dj\portal\views.py

Любые выражения, в нашем случае это конструкция цикла for, обрамляется фигурными скобками с процентами

{% for post in posts %}
core_dj\portal\templates\portal\home.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
   <!-- <h1>Portal Home Page</h1> -->
   {% for post in posts %}
        <h1>{{ post.title }}</h1>
        <p>By {{  post.author }} on {{ post.date_posted }}</p>
        <p>{{ post.content}}</p>
   {% endfor %}
</body>
</html>

Запускаем наш python wsgi servers смотрим на обновленную домашнюю страницу


Теперь настроим заголовок для нашего портала. Заголовок будет различаться в зависимости от того, на кокой странице находится пользователь. Снова отредактируем core_dj\portal\templates\portal\home.html

core_dj\portal\templates\portal\home.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% if title %}
        <title>Django Portal - {{ title }}</title>
    {% else %}
        <title>Django Portal</title>
    {% endif %}
</head>
<body>
   <!-- <h1>Portal Home Page</h1> -->
   {% for post in posts %}
        <h1>{{ post.title }}</h1>
        <p>By {{  post.author }} on {{ post.date_posted }}</p>
        <p>{{ post.content}}</p>
   {% endfor %}
</body>
</html>

И аналогичные изменения внесем в файл core_dj\portal\templates\portal\about.html

core_dj\portal\templates\portal\home.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% if title %}
        <title>Django Portal - {{ title }}</title>
    {% else %}
        <title>Django Portal</title>
    {% endif %}
</head>
<body>
    <h1>About Page</h1>
 
</body>
</html>

Так же изменим функцию about в файле core_dj\portal\views.py

core_dj/portal/views.py
def about(request):
    return render(request, 'portal/about.html', {'title': 'About'})

Теперь заголовки портала выглядят так:

Наследование шаблонов

Для удобства работы с шаблонами, создадим один базовый шаблон, от которого будут наследовать все остальные. По пути core_dj\portal\templates\portal создадим еще один файл – base.html. Выглядеть он будет так:

core_dj\portal\templates\portal\base.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% if title %}
        <title>Django Portal - {{ title }}</title>
    {% else %}
        <title>Django Portal</title>
    {% endif %}
</head>
<body>
    {% block content %}{% endblock%}
</body>
</html>

Шаблон home.html примет такие изменения

core_dj\portal\templates\portal\home.html
{% extends "portal\base.html" %}
{% block content %}
    {% for post in posts %}
        <h1>{{ post.title }}</h1>
        <p>By {{  post.author }} on {{ post.date_posted }}</p>
        <p>{{ post.content}}</p>
    {% endfor %}
{% endblock content %}

а шаблон about.html, теперь выглядит уот так уот

core_dj\portal\templates\portal\about.html
{% extends "portal\base.html" %}
{% block content %}
    <h1>About Page</h1>
{% endblock content %}

Подключение фреймворка Bootstrap

Работать будем с bootstrap 4 версии. Идем на официальный сайт getbootstrap.com и берем там все, что сможем унести. Копируем часть html кода, в файл core_dj\portal\templates\portal\base.html. После чего, он примет такой вид:

core_dj\portal\templates\portal\base.html
<!DOCTYPE html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
 
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
 
    {% if title %}
        <title>Django Portal - {{ title }}</title>
    {% else %}
        <title>Django Portal</title>
    {% endif %}
</head>
<body>
    <div class="container">
        {% block content %}{% endblock%}
    </div>
 
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</body>
</html>

Результат этого подключение, можно увидеть сразу в браузере. Bootstrap автоматически подключил собственны стили.


Подключение своих стилей

В файл core_dj\portal\templates\portal\base.html вставим вот такую часть кода, которая создаст нам каркас структуры сайта. Вставляем сразу после тега body

core_dj\portal\templates\portal\base.html
<header class="site-header">
  <nav class="navbar navbar-expand-md navbar-dark bg-steel fixed-top">
    <div class="container">
      <a class="navbar-brand mr-4" href="/">Django Blog</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggle" aria-controls="navbarToggle" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarToggle">
        <div class="navbar-nav mr-auto">
          <a class="nav-item nav-link" href="/">Home</a>
          <a class="nav-item nav-link" href="/about">About</a>
        </div>
        <!-- Navbar Right Side -->
        <div class="navbar-nav">
          <a class="nav-item nav-link" href="#">Login</a>
          <a class="nav-item nav-link" href="#">Register</a>
        </div>
      </div>
    </div>
  </nav>
</header>

Часть кода отвечающая за контент

core_dj\portal\templates\portal\base.html
<div class="container">
        {% block content %}{% endblock%}
    </div>

Приводим к такому виду

core_dj\portal\templates\portal\base.html
<main role="main" class="container">
  <div class="row">
    <div class="col-md-8">
      {% block content %}{% endblock %}
    </div>
    <div class="col-md-4">
      <div class="content-section">
        <h3>Our Sidebar</h3>
        <p class='text-muted'>You can put any information here you'd like.
          <ul class="list-group">
            <li class="list-group-item list-group-item-light">Latest Posts</li>
            <li class="list-group-item list-group-item-light">Announcements</li>
            <li class="list-group-item list-group-item-light">Calendars</li>
            <li class="list-group-item list-group-item-light">etc</li>
          </ul>
        </p>
      </div>
    </div>
  </div>
</main>

Непосредственно для подключения стилей, нам потребуется разместить файл содержащий их в директорию static. Так как в нашем проекте ее нет, создадим ее по пути core_dj\portal\static. В свою очередь, в этой директории создадим директорию с названием нашего приложения – core_dj\portal\static\portal. В ней разместим файл со стилями main.css

Для экономии места, полный листинг файлов шаблонов и стилей будет приведен по ссылке ниже.

Теперь самое время подключить нашу таблицу стилей. И идем в core_dj\portal\templates\portal\base.html и указываем наш файл со стилями.

core_dj\portal\templates\portal\base.html
# В самой верхней части файла, указываем на статические подключения
{% load static %}
# Собственно само подключение таблицы стилей
<link rel="stylesheet" type="text/css" href="{% static 'portal/main.css'%}">

Теперь отредактируем шаблон домашней страницы – core_dj\portal\templates\portal\home.html, а именно ту часть, что отвечает за публикацию, после посещения нашего барбершопа, он стал выглядеть так:

core_dj\portal\templates\portal\home.html
{% extends "portal\base.html" %}
{% block content %}
    {% for post in posts %}
        <article class="media content-section">
          <div class="media-body">
            <div class="article-metadata">
              <a class="mr-2" href="#">{{ post.author }}</a>
              <small class="text-muted">{{ post.date_posted }}</small>
            </div>
            <h2><a class="article-title" href="#">{{ post.title }}</a></h2>
            <p class="article-content">{{ post.content }}</p>
          </div>
        </article>
    {% endfor %}
{% endblock content %}

Псоле чего, центральная часть сайта принемает такой вид


Далее, отредактируем ссылки на нашем навбаре. Дадим им такие имена, какие были указаны в файле core_dj\portal\urls.py

core_dj\portal\urls.py
urlpatterns = [
    path('', views.home, name='portal-home'),
    path('about/', views.about, name='portal-about'),
]

Соответственно меняем линки в core_dj\portal\templates\portal\base.html

core_dj\portal\templates\portal\base.html
<div class="collapse navbar-collapse" id="navbarToggle">
            <div class="navbar-nav mr-auto">
              <a class="nav-item nav-link" href="{% url 'portal-home' %}">Home</a>
              <a class="nav-item nav-link" href="{% url 'portal-about' %}">About</a>
            </div>

Глобальный шаблон

Созданный нами шаблон, действует только в рамках приложения portal. Для того чтобы шаблон охватывал весь проект, нужно выполнить такую штуку.

В корне проекта, создадим директорию templates, в которой создадим файл base.html. Скопируем в него все содержимое файла core_dj\portal\templates\portal\base.html. А в файле core_dj\portal\templates\portal\base.html заменим все содержимое на такой нехитрый код:

core_dj\portal\templates\portal\base.html
{% extends 'base.html' %}

Для того, чт обы такая схема заработала в файле core_dj\core_dj\settings.py нужно указать наш базовый шаблон. В блоке TEMPLATES редактируем переменную DIRS

core_dj\core_dj\settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(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 - абсолютный путь до нашего проекта, он указан в том же файле settings.py и имеет такой вид:
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  • templates - директория созданная для глобального шаблона

Для того, чтобы увидеть как вычесляется абсолютный путь до файла, откроем консоль и по пути core_dj\core_dj\ запустим python.

python
Python 3.7.4 (default, Aug  9 2019, 18:34:13) [MSC v.1915 64 bit (AMD64)] :: Anaconda, Inc. on win32
>>> import os
>>> base = os.path.dirname(os.path.dirname(os.path.abspath('settings.py')))
>>> base
'C:\\Users\\UserName\\core_dj\\'
>>> os.path.join(base, 'templates')
'C:\\Users\\UserName\\core_dj\\templates'

После проведенной «шаблонизации», структура проекта имеет такой вид:

C:.
│   db.sqlite3
│   manage.py
│
├───core_dj
│   │   settings.py
│   │   urls.py
│   │   wsgi.py
│   │   __init__.py
│   │
│   └───__pycache__
│
├───portal
│   │   admin.py
│   │   apps.py
│   │   models.py
│   │   tests.py
│   │   urls.py
│   │   views.py
│   │   __init__.py
│   │
│   ├───migrations
│   │   │   __init__.py
│   │   │
│   │   └───__pycache__
│   │           __init__.cpython-38.pyc
│   │
│   ├───static
│   │   └───portal
│   │           main.css
│   │
│   ├───templates
│   │   └───portal
│   │           about.html
│   │           base.html
│   │           home.html
│   │
│   └───__pycache__
│
└───templates
        base.html                   

Ссылки

Полный листинг файлов шаблонов и стилей для приложения portal

шаблоны.txt · Последнее изменение: 2020/01/31 11:30 — admin