Блог

Дропшиппинг интернет-магазин на Django (часть 3)

3. Встраивание HTML-шаблона в проект Django. Создание базовой и главной страницы. Перенос статики

Внимание! Если у вас возникли проблемы с выполнением предыдущего этапа, то вы сможете зайти в соответствующий урок, скачать архив предыдущего этапа, инсталлировать его, и начать этот урок именно с того самого места, где закончился предыдущий!

Содержание курса:

Добавление в проект главной страницы html-шаблона и настройка статики

Итак, наш нестандартный чек-лист (в виде доработанного HTML-шаблона) создан и теперь самое время приступить к "зачёркиванию" его пунктов. Начнём с главной страницы.

Прежде всего необходимо убедиться, что в корень проекта были добавлены каталоги tamplates для html-файлов и static для файлов статики (css-, js-и image-файлов). И что в файл настроек проекта settings.py были добавлены пути этих каталогов относительно базовой директории.

Собственно, убедиться в этом совсем несложно: актуальная схема-дерево нашего проекта представлена на слайде ниже:

├── authentication
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── db.sqlite3
├── main
│   ├── asgi.py
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── requirements.txt
├── shop
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── static
├── templates
└── venv

Теперь копируем статику: копируем в папку проекта static всё содержимое папки asserts HTML-шаблона. Далее копируем главную страницу, пока так, как она есть (т.е. пока без выделения общей части в базовую страницу base-page.html). Просто скопируем файл шаблона index.html в папку templates нашего проекта.

Далее, нам нужно помнить, что для отображения страницы в Django-проекта необходимо, как минимум, 2 действия:

  • Указать url данной страницы, по которому в проекте она будет вызываться.
  • И создать специальную функцию (или класс), называемую view (или представление), которая будет запускаться при переходе по указанной ссылке и отображать нашу страницу.

  • Сейчас в нашем проекте помимо главной папки main присутствуют ещё две папки приложений: папка shop и папка authentication. Во всех этих трёх папках уже есть, или может быть добавлена пара файлов urls.py - views.py. Но только одна из них: пара из главной папки main может обеспечить url, в котором не будет дополнительной добавки фрагментов адреса url в виде /auth/ или /shop/. Иными словами ссылки (urls) из папки main будут вести на "чистый" адрес имени домена.

    Разумеется, совершенно логично, когда главная страница отображается по адресу имени домена. Так что можно сказать, что с местом размещения пары urls.py - views.py мы определились, осталось только добавить в папку main пока что недостающий там файл views.py. А далее сделать в этих файлах соответствующие записи:

    main/urls.py

    from django.contrib import admin
    from django.urls import path
    from shop import views
    
    urlpatterns = [
        path('', views.index, name='index'),
        path('admin/', admin.site.urls),
    ]

    Далее, создадим простейшее view, в задачи которого будет входить только рендеринг (создание) указанного шаблоне. Для его создания можно использовать готовый файл view одного из наших приложений, либо создать новый файл views.py в папке main.

    main/views.py

    from django.shortcuts import render
    
    
    def index(request):
        return render(request, 'index.html')

    Пробуем запустить, и видим, что главная страница отобразилаcь, но стили на ней полностью отсутствуют. Оно и понятно: и ссылки на стили теперь должны быть прописаны совершенно на другие пути (раньше файлы статики были в папке asserts, а теперь она находится в папке static), и сам способ написания этих ссылок тоже должен стать совершенно другим.

    • Во-первых, теперь каждая HTML-страница должна начинаться с команды загрузки статики {% load static %}.
    • А во-вторых, во всех ссылках путь ко всем файлам статики должен теперь выглядеть не так

    <link rel="stylesheet" href="../construct/assets/css/style.css">

    а вот так:

    <link rel="stylesheet" href="{% static '/css/style.css' %}">

    Обновляем страницу, и видим, что картина изменилась, но кроме надписи Loading... ничего не появляется. Значит надо обновить все ссылки на файлы статики главной страницы. И особенно, на файлы js в конце страницы...

    Ну вот, теперь что-то видно. Определённые стили появились, хотя далеко не всё. Чтобы появились все, надо последовательно "пройтись" по всем ссылкам и аккуратно и внимательно их изменить. Как видим, без минимального знания HTML на бекенде не обойтись.

    Выделяем общую часть всех страниц проекта в базовую страницу

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

    Прежде всего необходимо обратить внимание на тот факт, что все страницы нашего HTML-шаблона имеют одну общую часть, в которую входят header (включая главное меню) и footer. Эти элементы присутствуют абсолютно на всех страницах. Поэтому нет никакого смысла сначала дублировать вставку одного и того же кода, а потом ещё и мучиться с изменением ссылок на файлы статики. Будет куда разумнее, если мы выделим эту общую часть в отдельную базовую страницу base-page.html, и оставим на этой базовой странице места вставок для уникального контента из нужных нам страницы проекта.

    Теперь каждая HTML-страница, кроме базовой, будет иметь точно такую же структура, как и страница index.html:

    {% extends 'base-page.html' %}
    {% load static %}
    
    {% block title %}
        < Page Name >
    {% endblock title %}
    
    {% block container %}
        < Current Page Content >
    {% endblock container %}

    То есть теперь при загрузке страницы index.html сначала идёт загрузка базовой страницы base-page.html (extends 'base-page.html'), затем загружается статика для этой страницы (load static), и далее в указанные места вставок добавляются текущие значение блоков < Page Name > и < Current Page Content >.

    Аналогично будут оформлены и все прочие страницы. Например, для следующей страницы about-us.html нужно проделать те же самые операции:

    • Добавить новую строку с новым url в файл main/urls.py;
    • Добавить новою view в файл main/views.py;
    • И добавить в папку templates страницу about-us.html.

    main/urls.py

    from django.contrib import admin
    from django.urls import path
    from shop import views
    
    urlpatterns = [
        path('', views.index, name='index'),
        path('about/', views.about, name='about'),
        path('admin/', admin.site.urls),
    ]

    Далее, создадим простейшее view, в задачи которого будет входить только рендеринг (создание, построение) указанного шаблона. Для его создания можно использовать готовый файл view одного из наших приложений, либо создать новый файл views.py в папке main.

    main/views.py

    from django.shortcuts import render
    
    
    def about(request):
        return render(request, 'about-us.html')

    И последний третий шаг: добавляем в папку templates страницу about-us.html. Изменённый HTML-код этой страницы, по сути, теперь будете состоять только из того кода, что раньше находился между header'ом и footer'ом. А структура страницы about-us.html ничем не будет отличаться от страницы index.html.

    index.html

    {% extends 'base-page.html' %}
    {% load static %}
    
    {% block title %}
        < Page Name >
    {% endblock title %}
    
    {% block container %}
        < Current Page Content >
    {% endblock container %}

    Таким образом, после создания базовой страницы, мы можем в шаблонах всех остальных страниц сайта размешать только тот оригинальный HTML-код, которого нет в базовом шаблоне. Разумеется, не забывая при этом давать ссылку на базовый шаблон. И всё! Это невероятно уменьшает дублирование кода и позволяет легко вносить изменения во все страницы сайта сразу изменяя, всего лишь, код на базовой странице.

    Более подробно с со всеми деталями этого этапа вы сможете познакомиться из этого видео:






    Переход на следующий этап проекта