Лучшая практика для структуры рабочего каталога проекта Django. Разворачиваем Django приложение в production на примере Telegram бота

pip install Django==2.1.7

Option 2: Get the release candidate for 2.2 pip install --pre django Option 3: Get the latest development version

The latest and greatest Django version is the one that’s in our Git repository (our revision-control system). This is only for experienced users who want to try incoming changes and help identify bugs before an official release. Get it using this shell command, which requires Git :

git clone https://github.com/django/django.git

Additional information For the impatient:
  • Latest release:
    Checksums:
    Release notes:
  • Preview release:
    Checksums:
    Release notes:
Which version is better?

We improve Django almost every day and are pretty good about keeping the code stable. Thus, using the latest development code is a safe and easy way to get access to new features as they’re added. If you choose to follow the development version, keep in mind that there will occasionally be backwards-incompatible changes. You’ll want to pay close attention to the commits by watching Django on GitHub or subscribing to django-updates .

If you’re just looking for a stable deployment target and don’t mind waiting for the next release, you’ll want to stick with the latest official release (which will always include detailed notes on any changes you’ll need to make while upgrading).

Previous releases
  • Django 2.0.13:
    Checksums:
    Release notes:
  • Django 1.11.20 (LTS):
    Checksums:
    Release notes:

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

Мы создадим веб-приложение, у которого будет панель администратора и возможность загружать загадки, а у пользователей, соответственно, возможность отвечать на них. Во время разработки будут использоваться Python 3.4.3 и Django 1.9.1.

Устанавливаем Django

Делается это очень просто, в командной строке нужно написать: pip install Django==1.9.1 .

Создаем проект

Если вы правильно установили Django, то после запуска django-admin --version вы увидите текущую версию фреймворка. Теперь создадим проект. Это можно сделать следующим образом: django-admin startproject django_example .

Как только создание проекта будет завершено, взглянем на директорию нашего проекта:

  • django_example/__init__.py - пустой файл, который говорит Python, что данная директория должна восприниматься в качестве пакета.
  • django_example/settings.py содержит конфигурацию нашего проекта.
  • django_example/urls.py - здесь объявляются URL.
  • django_example/wsgi.py - с помощью него приложение может работать с веб-сервером по протоколу WSGI.
  • manage.py позволяет взаимодействовать с проектом.

Теперь пришло время запустить наше приложение. Для этого в командной строке нужно написать python manage.py runserver . После этого в адресной строке браузера нужно написать: http://127.0.0.1:8000/ . Если вы увидели «You have unapplied migrations; your app may not work properly until they are applied.», то не волнуйтесь, мы вернемся к этому чуть позже.

Создаем приложение

Определим различие между проектом и приложением. Приложение - это программа, которая что-то делает, а проект - это группа приложений.

Итак, приступим к созданию приложения. Это делается следующим образом: python manage.py startapp riddles .
Как только приложение создано, давайте напишем простой вид, по правилам Django все виды должны храниться в файле views.py .

riddles/views.py

From django.http import HttpResponse def index(request): return HttpResponse("Hello, World!")

Теперь, чтобы привязать наш вид к URL, создадим файл urls.py .

riddles/urls.py

From django.conf.urls import url from . import views app_name = "riddles" urlpatterns = [ url(r"^$", views.index, name="index"), ]

В urls.py мы должны написать следующее:

django_example/urls.py

From django.conf.urls import include, url from django.contrib import admin urlpatterns = [ url(r"^riddles/", include("riddles.urls")), url(r"^admin/", admin.site.urls), ]

Теперь, если мы запустим наше приложение http://127.0.0.1:8000/riddles/ , мы увидим «Hello, World!».

Установка базы данных

По умолчанию в Django используется SQLite, если она вас не устраивает, то вы с нашей статьей, в которой мы рассказываем, как безболезненно перейти с SQLite на MySQL.

Теперь откроем django_example/settings.py и взглянем на переменную INSTALLED_APPS , она хранит все приложения, которые активны в текущем проекте. По умолчанию она содержит:

  • django.contrib.admin - админка, скоро мы ей воспользуемся.
  • django.contrib.auth - система аутентификации.
  • django.contrib.contenttypes - фреймворк для content types.
  • django.contrib.sessions - сессионный фреймворк.
  • django.contrib.messages - фреймворк для отправки сообщений.
  • django.contrib.staticfiles - фреймворк для работы со статичными файлами.

Некоторые из этих приложений используют базы данных, но они еще не установлены, поэтому мы и видели «You have unapplied migrations; your app may not work properly until they are applied.». Поправить это можно следующим образом: python manage.py migrate . Вы должны увидеть следующее:

Operations to perform: Apply all migrations: admin, sessions, auth, contenttypes Running migrations: Rendering model states... DONE Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying sessions.0001_initial... OK

Теперь создадим нашу модель. Для начала создадим Riddle и Option . В Riddle будет содержаться загадка, в Option - один из возможных ответов на нее.

riddles/models.py

From django.db import models class Riddle(models.Model): riddle_text = models.CharField(max_length=255) pub_date = models.DateTimeField("date published") class Option(models.Model): riddle = models.ForeignKey(Riddle, on_delete=models.CASCADE) text = models.CharField(max_length=255) correct = models.BooleanField(default=False)

Данная модель обеспечивает Django информацией, необходимой для создания схемы базы данных и database-access API для доступа к объектам. Теперь нам нужно привязать наше приложение к нашему проекту, делается это следующим образом:

django_example/settings.py

INSTALLED_APPS = [ "riddles.apps.RiddlesConfig", "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", ]

После этого нужно сделать миграцию: python manage.py makemigrations riddles . Вы должны увидеть следующее:

Migrations for "riddles": 0001_initial.py: - Create model Option - Create model Riddle - Add field riddle to option

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

Проверить, что сделает миграция, можно так: python manage.py sqlmigrate riddles 0001 (0001 - версия миграции, которую мы хотим проверить). На выходе мы получим:

BEGIN; -- -- Create model Option -- CREATE TABLE "riddles_option" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "text" varchar(255) NOT NULL, "correct" bool NOT NULL); -- -- Create model Riddle -- CREATE TABLE "riddles_riddle" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "riddle_text" varchar(255) NOT NULL, "pub_date" datetime NOT NULL); -- -- Add field riddle to option -- ALTER TABLE "riddles_option" RENAME TO "riddles_option__old"; CREATE TABLE "riddles_option" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "text" varchar(255) NOT NULL, "correct" bool NOT NULL, "riddle_id" integer NOT NULL REFERENCES "riddles_riddle" ("id")); INSERT INTO "riddles_option" ("riddle_id", "id", "text", "correct") SELECT NULL, "id", "text", "correct" FROM "riddles_option__old"; DROP TABLE "riddles_option__old"; CREATE INDEX "riddles_option_a7c97949" ON "riddles_option" ("riddle_id"); COMMIT;

Заметьте, что команда sqlmigrate нужна только для проверки, каждый раз ее запускать необязательно.

Теперь мы можем начать пользоваться панелью администратора. Но для этого нам нужен пользователь. Создать его можно следующим образом: python manage.py createsuperuser . После этого запускаем сервер, если он не запущен, и переходим на http://127.0.0.1:8000/admin/ . Вы увидите следующее:

Теперь дадим админу возможность изменять наши модели. Делается это так:

riddles/admin.py

From django.contrib import admin from .models import Option, Riddle admin.site.register(Riddle) admin.site.register(Option)

Вот что получится в итоге:

Возьмите небольшую паузу и поиграйтесь с панелью администратора. Вы будете приятно удивлены тем, что умеет Django.

Главная страница

Что нам нужно для создания главной страницы?

  • Templates: скелет нашей страницы.
  • Views: функция на Python для отображения контента.

Начнем с шаблонов. Создадим папку templates внутри папки riddle , а в ней создадим index.html .

riddles/templates/index.html

Available Riddles {% if message %}

{{ message }}

  • {{ riddle.riddle_text }}
  • {% endfor %}
{% else %} {% endif %}

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

{{ riddle.riddle_text }} {% if error_message %}

{{ error_message }}

{% endif %} {% csrf_token %} {% for option in riddle.option_set.all %} {{ option.text }}
{% endfor %}

Первая строка загружает статические файлы, потом мы используем {% static "#" %} , где # - путь к вашему файлу. Аналогичная процедура проводится и для JavaScript.

Теперь вы можете создавать свои собственные приложения на Django.

Сборка пакетов имеет решающее значение для успешной реализации проекта с открытым исходным кодом. Ключевой составляющей правильной сборки является управление версиями. Так как проект имеет открытый исходный код, вы можете захотеть опубликовать пакет, чтобы реализовать все преимущества, предоставляемые сообществом разработчиков программ с открытым исходным кодом. В различных платформах или языках используются разные механизмы сборки пакетов, однако данная статья посвящена именно Python и его экосистеме сборки пакетов. В статье обсуждаются механизмы сборки пакетов, обеспечивающие основу для развития, а также приводится достаточно примеров, на основании которых можно сразу же приступать к действию.

Почему сборка пакетов так важна?

Помимо того, что это просто хороший тон, существуют еще три практические причины для поставки программного обеспечения в виде пакетов:

  • простота использования;
  • стабильность (при управлении версиями);
  • распространение.

При выборе приложения простота его установки учитывается пользователями далеко не в последнюю очередь, поэтому следует максимально упростить этот процесс. Сборка пакетов позволяет сделать программное обеспечение более доступным и простым в установке. Если установка не сложная, значит, пользователям будет проще приступить к работе с вашим программным обеспечением. Повысить доступность своего пакета при его публикации в каталоге пакетов Python (Python Package Index — PyPI) можно посредством таких утилит как pip или easy_install . (См. для получения дополнительной информации по данным средствам.)

Кроме того, управление версиями пакетов позволяет пользователям «закрепить» свои проекты, использующее ваше программное обеспечение, за его определенной версией. Например, закрепление за Pinax версии 0.9a2.dev1017 будет выглядеть таким образом:

Pinax==0.9a2.dev1017

Это принудительно свяжет проект с Pinax версии 0.9a2.dev1017.

Управление версиями обеспечивает лучшую устойчивость при внесении изменений в программное обеспечение в будущем, в результате которых могут возникнуть конфликты в интерфейсах. В итоге ваши пользователи точно знают, что они получают, и им легче отслеживать различия в разных версиях. К тому же, разработчикам проектов точно известно, над чем они работают.

Наиболее популярным методом публикации пакетов на PyPI (или на вашем собственном дистрибутивном сервере) является создание дистрибутива исходного кода для его свободной загрузки. Дистрибутив исходного кода — это стандартный способ сборки кода вашего проекта в качестве распространяемого модуля. Можно также создавать бинарные дистрибутивы, но для целей открытого использования имеет смысл также распространять свой код. Создавая дистрибутивы исходного кода, вы облегчаете пользователям процесс нахождения программного обеспечения в сети Интернет с помощью автоматизированных средств, а также его загрузки и установки. Этот процесс помогает не только в разработке на локальных системах, но и в развертывании вашего программного обеспечения.

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

Анатомия файла setup.py

Одно из предназначений сценария setup.py — это исполнение сборки пакетов вашего программного обеспечения и загрузки его на дистрибутивные серверы. На различных популярных репозиториях Python вы можете найти сценарии setup.py различного содержания. В данной статье рассмотрены основные из них. См. раздел для получения дополнительной информации.

Файл setup.py может использоваться для различных целей, но ниже мы приводим вариант, который позволяет выполнить следующие команды:

python setup.py register python setup.py sdist upload

Первая команда, register , получает информацию, которую выдает функция setup() сценария setup.py, и создает запись в PyPI для вашего пакета. Она ничего не загружает, вместо этого она создает метаданные о вашем проекте с тем, чтобы впоследствии вы могли выгрузить и разместить там свои версии ПО. Следующие две команды связаны: sdist upload создает дистрибутив исходного кода, а затем выгружает его в PyPI. Тем не менее, существуют несколько необходимых условий, таких как настройка собственного конфигурационного файла.pypirc и собственно запись содержимого в файл setup.py.

Прежде всего, сконфигурируйте файл.pypirc. Он должен находиться в основном каталоге, который может быть разным в зависимости от используемой операционной системы. В операционных системах UNIX®, Linux® и Mac OS Xзайти в этот каталог можно, набрав cd ~/ . Содержимое файла должно включать ваши учетные данные PyPI, как показано в.

Листинг 1. Типовой файл.pypirc index-servers = pypi username:xxxxxxxxxxxxx password:xxxxxxxxxxxxx

Далее переходите в PyPI и зарегистрируйтесь для создания учетной записи (не волнуйтесь — это бесплатно). Введите такое же имя пользователя и пароль, что и в файле.pypirc каталога PyPI, и убедитесь, что файл называется именно ~/.pypirc .

Теперь при написании своего сценария setup.py вам необходимо решить, что будет отображаться на индексной странице PyPI, и определиться с названием проекта. Начнем с копирования шаблона для setup.py, который я использую для проектов (см. ). Пропустив импортирование и функции, взгляните на нижнюю часть шаблона и подумайте, что вам нужно изменить с учетом особенностей вашего проекта. См. для получения ссылки на полный сценарий.

Листинг 2. Шаблон setup.py PACKAGE = "" NAME = "" DESCRIPTION = "" AUTHOR = "" AUTHOR_EMAIL = "" URL = "" VERSION = __import__(PACKAGE).__version__ setup(name=NAME, version=VERSION, description=DESCRIPTION, long_description=read("README.rst"), author=AUTHOR, author_email=AUTHOR_EMAIL, license="BSD", url=URL, packages=find_packages(exclude=["tests.*", "tests"]), package_data=find_package_data(PACKAGE, only_in_packages=False), classifiers=[ "Development Status:: 3 - Alpha", "Environment:: Web Environment", "Intended Audience:: Developers", "License:: OSI Approved:: BSD License", "Operating System:: OS Independent", "Programming Language:: Python", "Framework:: Django", ], zip_safe=False,)

Во-первых, следует помнить, что этот шаблон подразумевает наличие в вашем проекте двух различных файлов. Первый используется для длинного описания (long_description). Он считывает содержимое файла README.rst, находящегося в той же директории, что и setup.py, и передает это содержимое как строку в параметр long_description . Этот файл заполняет целевую страницу в PyPI, поэтому желательно дать в нем краткое описание проекта и привести несколько примеров его использования. Второй файл — файл пакетов __init__.py . Мы не приводим здесь его развернутого описания, однако когда строка, которая определяет переменную VERSION, импортирует ваш пакет, Python требуется файл __init__.py, поэтому в данном модуле следует определить переменную с названием __version__ . Пока достаточно записать это строкой:

# __init__.py __version__ = "0.1"

Теперь взглянем на остальные исходные параметры.

  • PACKAGE — это пакет Python в вашем проекте. Это папка верхнего уровня, содержащая модуль __init__.py, который должен находиться в той же директории, что и файл setup.py, например: /- |- README.rst |- setup.py |- dogs |- __init__.py |- catcher.py

    Итак, в данном случае вашим пакетом будет dogs .

  • Параметр NAME обычно схож или совпадает с названием пакета PACKAGE, но вы можете задать любое имя в зависимости от ваших предпочтений. NAME — это параметр, по которому пользователи будут ссылаться на ваше программное обеспечение, имя, под которым ваше программное обеспечение будет отображаться в PyPI и, что более важно, под которым пользователи будут его устанавливать (например, pip install NAME).
  • DESCRIPTION — краткое описание вашего проекта. Одного предложения будет достаточно.
  • AUTHOR и AUTHOR_EMAIL — это соответственно: ваше имя и адрес электронной почты. Эта информация не обязательна, но указать свой адрес электронной почты для пользователей, которые пожелают обратиться к вам с вопросами по проекту, это правило хорошего тона.
  • URL — это URL-адрес проекта. Этот параметр может быть как Web-сайтом проекта или репозиторием Github, так и любым другим URL-адресом. Эта информация также не обязательна.

Возможно, вы пожелаете указать лицензионные условия и классификаторы. Более детальная информация о создании файла setup.py приведена в документации по Python. (См. .)

Управление версиями

Управление версиями само по себе является обширной темой, однако его следует упомянуть в контексте сборки пакетов, так как нельзя провести правильную сборку пакетов без надлежащего управления версиями. Управление версиями — это форма общения с вашими пользователями, также с его помощью пользователи могут создавать более стабильные и надежные приложения. При помощи управления версиями вы сообщаете своим пользователям о внесенных изменениях и указываете точные рамки, где были произведены эти изменения.

Стандарт по управлению версиями пакетов Python можно найти в PEP-386 (Предложение по развитию Python) (см. .) В нем прописаны правила практического характера. Даже если вы не читали, не поняли или даже не согласны с PEP, все же разумнее придерживаться установленных в нем правил, так как именно они все чаще применяются при создании разработчиками приложений Python.

Кроме того, управление версиями необходимо не только для разработки стабильных версий, загружаемых в PyPI, но также полезно для разработки версий с суффиксом devNN . Как правило, размещение разрабатываемых версий в PyPI не поощряется, но можно сделать их общедоступными посредством настройки собственного общедоступного (или закрытого) дистрибутивного сервера. В этом случае пользователи, которые желают воспользоваться последней версией, могут указать это в своем pip -файле requirements.txt. Ниже приведено несколько примеров управления версиями:

1.0.1 # 1.0.1 final release 1.0.2a # 1.0.2 Alpha (for Alpha, after Dev releases) 1.0.2a.dev5 # 1.0.2 Alpha, Dev release #5 Публикация

Пользователям не удастся отыскать и установить ваше программное обеспечение, если оно не будет опубликовано. Обычно пакеты публикуются в PyPI. Настроив свой конфигурационный файл.pypirc и передав команду upload в setup.py, вы передадите пакет в PyPI. Как правило, эта операция производится совместно с созданием дистрибутива исходного кода:

python setup.py sdist upload

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

python setup.py sdist upload -r mydist Настройка собственного дистрибутивного сервера

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

pip install MyPackage

Установить последнюю стабильную версию в PyPI. Но если вы позднее добавите разрабатываемые версии, то эта команда остановит выполнение и установит последнюю версию, т. е. разрабатываемую версию. Как правило, полезно всегда закреплять проекты за определенной версией, но это делают не все пользователи. Поэтому следует убедиться в том, что, если номер версии не указан, по умолчанию возвращается последняя стабильная версия.

Одним из способов убить одним выстрелом двух зайцев (предоставлять только стабильные версии для использования pip по умолчанию и обеспечить пользователям возможность устанавливать пакеты разрабатываемых версий) является создание собственного дистрибутивного сервера. Проект Pinax применяет эту технологию для всех своих разрабатываемых версий на сайте http://dist.pinaxproject.com. (См. .)

Дистрибутивный сервер представляет собой каталог, работающий по протоколу HTTP и предоставляющий доступ к файлам на вашем сервере. Он должен иметь следующую файловую структуру:

/index-name/package-name/package-name-version.tar.gz

В дальнейшем при желании сервер можно сделать закрытым путем конфигурирования Basic-Auth на своем Web-сервере. Вы также можете добавить некоторые другие средства для выгрузки дистрибутивов исходного кода. Для этого необходимо добавить код управления выгрузкой, разобрать название файла и создать пути по каталогу, которые бы соответствовали приведенной выше схеме. Такая структура принята для проектов Pinax с использованием нескольких репозиториев.

pip и virtualenv

Хотя данная статья посвящена в основном сборке пакетов, дабы отдать должное тем преимуществам, которые сборка пакетов и управление версиями дают вашим пользователям, этот раздел описывает использование пакетов.

Инструмент pip можно установить напрямую, однако я рекомендую использовать его в рамках функциональности virtualenv . (См. .) Я также советую прибегать к virtualenv во всех случаях, когда вы имеете дело с Python, так как окружение Python при этом остается незагроможденным. Подобно тому, как виртуальная машина позволяет запускать несколько операционных систем одновременно, virtualenv позволяет запускать несколько окружений Python одновременно. Я ничего не устанавливаю в своей системе Python, а просто создаю новое виртуальное окружение для каждого нового проекта или утилиты, над которыми работаю.

Теперь, когда инструмент virtualenv установлен, можно и немного поиграть:

$ mkvirtualenv -no-site-packages testing $ pip install Pinax $ pip freeze|grep Pinax $ pip uninstall Pinax $ pip install -extra-index-url=http://dist.pinaxproject.com/fresh-start/ Pinax==0.9a2.dev1017 $ pip freeze|grep Pinax

Обратите внимание, что первая установка pip загружается и устанавливается с PyPI. Команда pip freeze выводит все версии пакетов, установленных в текущем virtualenv . Команда pip uninstall делает именно то, о чем говорит ее название: удаляет себя из virtualenv . Затем мы устанавливаем разрабатываемую версию из репозитория перезагрузки по адресу http://dist.pinaxproject.com, чтобы получить разрабатываемую версию Pinax 0.9a2.dev1017.

Переходить на Web-сайт, загружать tar-архивы и создавать коды символических ссылок (symlink) на каталог site-packages не требуется. (Раньше я так и делал, и это вызывало много проблем.) Все это ваши пользователи получают благодаря хорошей сборке пакетов, публикации и управлению версиями созданного проекта.

Заключение

Надеюсь, материала, изложенного в данной статье, достаточно для того, чтобы вы смогли приступить к работе. В разделе приведены ссылки на документацию, которая может помочь вам глубже разобраться в упомянутых вопросах. Если у вас возникнут какие-либо вопросы, заходите на Freenode и ищите меня в таких разделах чата как #pinax и #django-social (по псевдониму "paltman") или в Twitter (@paltman).

Django – это мощный фреймворк для создания приложений Python. Такой полнофункциональный фреймворк, как Django, значительно ускоряет процесс создания и развёртывания приложения, беря на себя общее структурирование кода; таким образом, разработчик может сосредоточиться на уникальности и контенте сайта.

В данном руководстве рассматриваются различные методы установки Django на сервер Ubuntu 14.04, а также начало работы с этим фреймворком.

Методы установки Django

Существует несколько различных методов установки Django, каждый из которых имеет свои преимущества в определённых ситуациях.

  • Глобальная установка Django из пакета. Официальный репозиторий Ubuntu предоставляет пакеты Django, которые можно без труда установить при помощи менеджера пакетов apt. Этот метод очень прост, но не так гибок, как другие методы. Кроме того, репозиторий может содержать несколько устаревшую версию пакета Django.
  • Глобальная установка Django при помощи pip. Инструмент pip – это менеджер пакетов Python. С его помощью можно выполнить общесистемную установку Django. Он, как правило, предоставляет последнюю доступную версию пакета. Однако глобальные (общесистемные) установки всегда менее гибки.
  • Установка через pip в Virtualenv. Пакет virtualenv позволяет создавать автономные окружения для разных проектов. При помощи этой технологии можно установить Django в каталог проекта, при этом не повлияв на систему в целом. Это позволяет задавать индивидуальные настройки для каждого проекта. Виртуальное окружение (или среда) – гораздо более гибкий вариант установки пакета.
  • Установка разрабатываемой версии через Git. Чтобы установить последнюю разрабатываемую версию вместо стабильного релиза, нужно получить код из репозитория git . Это предоставит новейшие функции и исправления программы; установить такую версию можно как глобально, так и локально. Но имейте в виду: разрабатываемые версии нестабильны.

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

Глобальная установка Django из пакета

Процесс установки Django из официального репозитория Ubuntu очень прост. Для начала нужно обновить список локальных пакетов при помощи apt, а затем установить пакет python-django.

sudo apt-get update
sudo apt-get install python-django

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

django-admin --version
1.6.1

Появившийся номер версии значит, что установка прошла успешно.

Обратите внимание : Эта версия не является последней доступной версией Django.

Глобальная установка через pip

Чтобы глобально установить последнюю стабильную версию Django, используйте инструмент pip, менеджер пакетов Python. Чтобы установить pip, нужно сначала обновить список пакетов:

sudo apt-get update

Чтобы установить pip для Python 2, введите:

Чтобы установить pip для Python 3, используйте:

Теперь менеджер пакетов pip установлен, можно приступать к установке Django. Для Python 2 введите:

sudo pip install django

Для Python 3 наберите:

sudo pip3 install django

Чтобы убедиться, что установка прошла должным образом, введите:

django-admin --version
1.7.5

Как видите, pip предоставляет более новый релиз Django, чем репозиторий Ubuntu.

Установка Django через pip в Virtualenv

Вероятно, наиболее гибким вариантом установки является использование virtualenv. Этот инструмент позволяет создавать виртуальные окружения Python, в которые можно устанавливать любые необходимые пакеты, не влияя на систему в целом. Благодаря virtualenv можно выбирать пакеты для проектов на индивидуальной основе и при этом не беспокоиться о конфликте зависимостей.

Дл начала нужно установить менеджер pip из официального репозитория Ubuntu. Обновите список пакетов:

sudo apt-get update

Для Python 2:

sudo apt-get install python-pip

Для Python 3:

sudo apt-get install python3-pip

После установки pip его можно использовать для установки пакета virtualenv.

Для Python 2 введите:

sudo pip install virtualenv

Для Python 3:

sudo pip3 install virtualenv

Теперь можно создать индивидуальную виртуальную среду для любого проекта. Создайте каталог нового проекта и перейдите в него:

mkdir ~/newproject
cd ~/newproject

Создайте виртуальное окружение в каталоге проекта:

virtualenv newenv

Примечание : Замените условное название newenv своим названием.

Эта команда создаст автономную среду, установит Python и pip в изолированный каталог. Созданный каталог будет содержать файловую иерархию для установки пакетов.

Чтобы установить пакеты в изолированную среду, включите её:

source newenv/bin/activate

После этого командная строка изменится, что говорит о том, что виртуальная среда была включена. Она будет выглядеть примерно так:

(newenv)username@hostname:~/newproject$.

В новом окружении используйте pip для установки Django. Вне зависимости от того, какую версию Python вы используете, в виртуальной среде нужно запускать только команду pip. Кроме того, при локальной установке не нужно использовать sudo.

pip install django

Убедитесь, что программа установлена успешно.

django-admin --version
1.7.5

Чтобы покинуть виртуальную среду, используйте команду:

После этого командная строка примет свой стандартный вид. Чтобы снова включить виртуальную среду, вернитесь в каталог проекта и введите:

cd ~/newproject
source newenv/bin/activate

Установка разрабатываемой версии Django из git

Чтобы установить разрабатываемую версию Django, загрузите её из репозитория git.

Для этого установите git при помощи стандартного менеджера пакетов apt. Обновите список пакетов:

sudo apt-get update

А затем установите git и менеджер пакетов pip, который понадобится позже для установки Django. Для Python 2 используйте:

sudo apt-get install git python-pip

Для Python 3:

sudo apt-get install git python3-pip

После установки git клонируйте репозиторий Django. Он содержит новейшие функции и исправления, но не является стабильным. Чтобы клонировать репозиторий в каталог django-dev в домашнем каталоге, введите:

git clone git://github.com/django/django ~/django-dev

После этого установите его при помощи pip. Используйте флаг -e для установки в режиме editable, поскольку это необходимо при установке через систему контроля версий. Для Python 2:

sudo pip install -e ~/django-dev

Для Python 3:

sudo pip3 install -e ~/django-dev

Введите следующую команду, чтобы убедиться, что установка прошла успешно:

django-admin --version
1.9.dev20150305171756

Примечание : Этот метод можно применить в виртуальной среде и таким образом изолировать нестабильную версию Django.

Создание проекта Django

После установки Django ознакомьтесь с основами использования этого фреймворка.

Для создания проекта используется команда django-admin:

django-admin startproject projectname
cd projectname

Эта команда создаст каталог projectname в текущем каталоге и поместит в него скрипт управления и другой каталог по имени projectname с текущим кодом.

Примечание : Находясь в каталоге проекта, созданном при помощи virtualenv, Django может разместить скрипты управления и внутренние каталоги в текущем каталоге при помощи следующей команды (обратите внимание на точку в конце стоки):

django-admin startproject projectname .

Чтобы сгенерировать базу данных в более новых версиях Django (по умолчанию используется SQLite), введите:

python manage.py migrate

Если команда migrate не работает, значит, текущая версия Django является более старой и не поддерживает её. В таком случае используйте:

python manage.py syncdb

При этом Django попросит создать учётную запись администратора; укажите имя пользователя, электронный адрес и пароль.

При использовании команды migrate нужно создать учётную запись администратора вручную. Для этого наберите:

python manage.py createsuperuser

Программа также запросит имя пользователя, адрес электронной почты и пароль.

Создав пользователя, можно запустить сервер разработки Django, чтобы ознакомиться с внешним видом нового проекта. Имейте в виду: этот сервер нужно использовать только в процессе разработки, для производства он не подходит. Запустите:

python manage.py runserver 0.0.0.0:8000

В браузере посетите IP-адрес, задав порт:

server_ip_address:8000

Это откроет приветственную страницу Django.

server_ip_address:8000/admin

Введите имя и пароль администратора, чтобы получить доступ к панели управления.

Ознакомившись со стандартным проектом, остановите сервер разработки, введя в терминал CTRL-C. Этот стандартный проект Django является структурной основой для разработки уникального сайта. Чтобы узнать, как создавать пользовательские приложения и настроить свой сайт, читайте документацию Django.

Итоги

Итак, теперь на сервер установлен мощный фреймворк Django, обеспечивающий вас всеми необходимыми инструментами для разработки веб-приложений. Полноценный фреймворк Django способен значительно ускорить процесс разработки, позволяя вам сосредоточиться на уникальности приложения.

Tags: ,

Я уже очень давно слежу за развитием проекта DjangoCMS и честно скажу что он не всегда мне нравился. Но постепенно команда проекта исправила многие косяки и сделала эту CMS по-настоящему удобной, гибкой и функциональной. После этого я стал практически фанатом DjangoCMS и использую его в некоторых своих проектах (например этот блог). Сегодня я подробно расскажу что такое DjangoCMS , в каких случаях его удобно применять и покажу как с помощью него создать простой сайт. Надеюсь вы тоже полюбите этот инструмент:)

На данный момент основная проблема DjangoCMS - отсутствие нормальной документации. Первое что я нашёл на официальном сайте проекта , это инструкция как создать сайт с помощью DjangoCMS и развернуть его на облачной платформе Divio Cloud . Из этой инструкции конечно можно выцепить какое-то количество полезной информации, но я как разработчик, жду совсем другого, тем более что я не планирую использовать Divio Cloud , а хочу развернуть приложение на DjangoCMS где-нибудь у себя. Самое интересное, что существует официальная документация для разработчиков по DjangoCMS , но данную ссылку я нашёл в файле README.md из репозитория проекта на GitHub, в то время как на сайте её почему-то нет.

Есть одна вещь, за которую стоит отдельно похвалить команду Divio - грамотная поддержка в online-чате на сайте проекта DjangoCMS , куда можно задавать вопросы любой сложности! Многие вещи о которых не сказано в документации я узнал лично от ребят из Divio во время переписки с ними. Там есть и наши соотечественники которые отвечали по русски, за что им отдельный респект:)

Хватит лирики, приступаем к созданию собственного сайта на DjangoCMS !

Установка DjangoCMS

В начале необходимо создать и активировать виртуальное окружение для нашего проекта. Для этого выполните команду:

Virtualenv env source env/bin/activate

Если вы хотите использовать в своём проекте Python 3 , то первую команду нужно заменить на:

Virtualenv --python=/usr/bin/python3.5 env

Только не забудьте проверить правильность пути к интерпретатору Python 3 , так как у вас он может отличаться.

После того как виртуальное окружение создано и активировано нам нужно поставить установщик DjangoCMS - пакет djangocms-installer :

Pip install djangocms-installer

djangocms-installer ставит все необходимые пакеты для работы DjangoCMS . После этого ваше виртуальное окружение начинает поддерживать команду djangocms , которой мы скоро воспользуемся.

Создаём директорию для нашего проекта и переходим в неё:

Mkdir django_cms_project cd django_cms_project

И наконец создаём наше приложение на DjangoCMS с помощью команды:

Djangocms -f -p . django_cms_example

  • Флаг -f говорит о том что дополнительно будет установлен инструмент Django Filer , который отвечает за работу с файловой системой. Мне данный инструмент нравится и я рекомендую его использовать.
  • Флаг -p с точкой (-p . ) задаёт текущую директорию как родительскую для проекта.
  • djangocms_blog - название нашего приложения. Вы можете указать своё собственное.

В старых версиях установщик DjangoCMS задавал вопросы по конфигурированию приложения во время установки. В новой версии приложение конфигурируется автоматически, а так же создаётся суперпользователь с логином admin и паролем admin . После установки вы можете запустить приложение командой:

Python manage.py runserver

После выполнения команды откройте в браузере ссылку http://127.0.0.1:8000/ . Если всё сделано правильно, вы должны увидеть форму входа в панель администрирования Django :

Для входа просто введите логин admin и пароль admin . На этом процесс установки DjangoCMS можно считать завершённым.

Настройка

Откройте в своей любимой IDE (лично я предпочитаю PyCharm ) только что созданный проект. В моём случае файлы проекта располагаются в директории djangocms_blog_project . Структура созданного проекта должна быть примерно такой:

Как Вы видите, это обычный Django -проект, только с прикрученным DjangoCMS в настройках (файл settings.py ). В целом наш проект и так прекрасно запускается и работает, но Вы должны помнить что по умолчанию будет использоваться база данных SQLite , которая хорошо подходит для отладки, но совсем не подходит для работы в реальных условиях. Кроме этого DjangoCMS очень много информации хранит именно в базе: контент, меню, список страниц, настройки каждой страницы, посты и т.д. То есть при переходе на другую базу данных придётся делать миграцию и я рекомендую сразу использовать ту базу данных, дамп которой можно потом перенести на продакшен. Но это просто рекомендация, можно успешно отладить приложение, используя SQLite и фейковую информацию на страницах, а затем на новой базе собрать чистовой вариант уже на отлаженных шаблонах. Или же, как правильно заметил Dmytro Kyrychuk в комментариях, использовать команды manage.py dumpdata и loaddata (эти команды подробно описаны тут: https://docs.djangoproject.com/en/1.10/ref/django-admin/ ​) для того, чтобы сдампить одну базу в JSON и восстановить дамп уже на другой базе.

Так как мой проект демонстрационный, я оставляю настройки базы данных без изменений:

DATABASES = { "default": { "CONN_MAX_AGE": 0, "ENGINE": "django.db.backends.sqlite3", "HOST": "localhost", "NAME": "project.db", "PASSWORD": "", "PORT": "", "USER": "" } }

Других настроек на данном этапе не требуется.

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

Прежде чем создавать страницы нашего сайта-блога нам нужны шаблоны на основе которых будут создаваться эти самые страницы. Наверняка вы захотите использовать собственный неповторимый дизайн чтоб было лучше чем у соседа, поэтому нам нужно в начале погрузиться в вёрстку. Шаблоны DjangoCMS это обычные файлы в формате .html с некоторым количеством шаблонных тегов Django и DjangoCMS . При создании нового проектаавтоматически генерируется 4 шаблона в папке templates (в моём случае djangocms_blog_project/djangocms_blog/templates) :

  • base.html - базовый шаблон, от которого наследуются все остальные шаблоны
  • fullwidth.html - шаблон полноразмерной страницы с контентом на всю ширину экрана
  • sidebar_left.html - страница с левым сайдбаром
  • sidebar_right.html - страница с правым сайдбаром

Кроме того, список шаблонов обязательно должен быть задан в settings.py в переменной CMS_TEMPLATES для того чтобы можно было выбрать нужный шаблон в интерфейсе при создании новой страницы сайта. По умолчанию у нас сконфигурировано 3 шаблона (все кроме base.html ):

CMS_TEMPLATES = (## Customize this ("fullwidth.html", "Fullwidth"), ("sidebar_left.html", "Sidebar Left"), ("sidebar_right.html", "Sidebar Right"))

Тут всё просто: нужно задать реальное название файла шаблона и произвольное название, которое будет отображаться в интерфейсе. Если вы создаёте новый шаблон, то в обязательном порядке вносите его в CMS_TEMPLATES , иначе вы не сможете им воспользоваться.

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

Выберите пункт Новая страница (Создать страницу рядом с текущей) и нажмите Далее . Откроется вот такое окно:

Заполните заголовок (Главная ), путь к странице (index ) и содержимое (Hello world! ), а затем нажмите кнопку Создать . Всё! Страница готова:

Теперь в верхнем меню выберите Страница > Шаблоны :

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

Теперь предлагаю подробно разобрать код шаблона fullwidth.html , но так как он наследуется от base.html , то начнём с базового шаблона:

{% block title %}This is my new project home page{% endblock title %} .nav { padding-left: 0; } .nav li { display: inline; list-style-type: none; padding-right: 20px; } .container { width: 940px; margin: 0 auto } .content { float: left; width: 80%; } .sidebar { float: left; width: 20%; } {% render_block "css" %} {% cms_toolbar %} {% render_block "js" %}

Что тут происходит? Да ничего особенного. В первой строке мы загружаем шаблонные теги:

  • cms_tags - теги DjangoCMS (http://docs.django-cms.org/en/release-3.4.x/reference/templatetags.html)
  • menu_tags - теги для управления меню (http://docs.django-cms.org/en/release-3.4.x/reference/navigation.html)
  • sekizai_tags - теги django-sekizai (https://django-sekizai.readthedocs.io/en/latest/)

Так же у нас в шаблоне 2 блока, которые можно переопределить в дочерних шаблонах: {% block title %} и {% block content %} .

Кроме этого у нас есть:

  • тег ответственный за отображение тулбара DjangoCMS - {% cms_toolbar %}
  • теги django-sekizai , которые отвечают за размещение блоков со ссылками на css и js в определённых частях страницы - {% render_block "css" %} и {% render_block "js" %}
  • тег, ответственный за отображение меню - {% show_menu 0 100 100 100 %}

Всё остальное вы и так знаете. Переходим к шаблону fullwidth.html :

{% extends "base.html" %} {% load cms_tags %} {% block title %}{% page_attribute "page_title" %}{% endblock title %} {% block content %} {% placeholder "content" %} {% endblock content %}

По факту перед нами стандартный шаблон Django отнаследованный от base.html . Из интересного тут 2 тега DjangoCMS :

  • тег {% page_attribute "page_title" %} - отображает атрибут страницы page_title в блоке title . Данный атрибут задаётся при создании страницы и является её заголовком. Все атрибуты можно просмотреть в документации .
  • тег {% placeholder "content" %} - это очень важный тег, который задаёт изменяемую часть страницы в блоке content . Количество плейсхолдеров на странице может быть неограниченным, главное чтоб название каждого плейсхолдера было уникальным. В панели администратора DjangoCMS можно менять содержимое любого плейсхолдера на своё усмотрение, например туда можно добавить текст, ссылку, картинку и т.д., а можно всё сразу и в любых комбинациях:)

Вот вы уже имеете некоторое представление о шаблонах DjangoCMS . Приведённые выше шаблоны я полностью изменю и доработаю, так как хочу чтобы сайт имел красивый дизайн. Это всё реализуется очень просто, но прежде чем менять шаблоны, давайте заглянем в панель администрирования DjangoCMS , для того чтобы лучше разобраться с плейсхолдерами. Нажмите кнопку Структура на верхней панели и вы увидите вот такую страницу:

Содержимое - это наш плейсхолдер content из шаблона fullwidth.html . Он содержит один единственный плагин, который отображает строчку Hello world! . Вы можете в любой момент отредактировать содержимое плагина, а так же добавлять другие плагины в плейсхолдер и даже создавать свои собственные плагины (об этом я расскажу в другой статье).

Для наглядности добавим ещё один плагин в плейсхолдер content . Для этого нажмите кнопку + и в появившемся окне выберите из списка плагин Google Map :

В открывшемся окне задайте название карты (поле MAP TITLE ), а так же широту и долготу своего города (поля LATITUDE и LONGITUDE ). В качестве названия у меня просто слово Карта , широта 55.751244 , долгота 37.618423 :

В верхней панели появилась синяя кнопка Опубликовать изменения страницы . Нажмите её и вы увидите обновлённую главную страницу с картой:

Вот так легко и просто можно управлять содержимым страницы в DjangoCMS .

Теперь я покажу как кардинально изменить дизайн сайта. Больше всего мне нравится в DjangoCMS то что можно взять практически любой html -шаблон и с минимальными изменениями встроить его в свой проект. В качестве примера я нашёл в интернете бесплатный адаптивный шаблон, свёрстанный с помощью CSS -фреймворка Bootstrap .

Для начала изменим содержимое базового шаблона base.html :

{% load cms_tags menu_tags sekizai_tags %} {% render_block "css" %} {% cms_toolbar %} Меню Меню Алексей Кутепов

{% block header %} {% placeholder "title" %} {% placeholder "sub_title" %} {% endblock header %} {% block content %}{% endblock content %} {% render_block "js" %}

Я не буду подробно разбирать этот код, так как статья про DjangoCMS , а не про вёрстку. Тем более вы можете использовать любой другой шаблон вместо этого или создать свой собственный. Данный шаблон я брал "как есть" и дополнил его тегами Django и DjangoCMS , о которых мы сейчас и поговорим.

Как всегда в самом начале мы должны загрузить все необходимые шаблонные теги:

{% load cms_tags menu_tags sekizai_tags %}

{% block title %}Сайт Алексея Кутепова{% endblock title %}

{% render_block "css" %}

Обратите внимание на переменную {{ STATIC_URL }} - в место него Django автоматически подставляет путь до папки со статикой. Так же в конце присутствует тег {% render_block "css" %} , который на данном этапе бесполезен, но при усложнении шаблона может здорово помочь: вместо этого тега можно динамически подставлять таблицы стилей в зависимости от определённых условий.

После тега нужно не забыть поставить шаблонный тег {% cms_toolbar %} , так как он отвечает за отображение верхней панели инструментов в режиме редактирования сайта. Как вы могли убедиться, мы её используем довольно часто и без неё у нас просто не будет возможности вносить изменения.

Меню Меню Алексей Кутепов

В шаблоне предусмотрен красивый хедер с фоновым изображением. Код, который отвечает за отображение хедера я заключил в блок header для того чтобы его можно было переопределить в дочерних шаблонах. Кроме того, в хедере у нас есть заголовок и подзаголовок, вместо которых я добавил плейсхолдеры title и sub_title , для того чтобы их можно было динамически изменять. При загрузке фонового изображения обязательно используется переменная {{ STATIC_URL }} :

{% block header %} {% placeholder "title" %} {% placeholder "sub_title" %} {% endblock header %}

После хедера идёт блок content , с которым вы знакомы по предыдущему шаблону:

{% block content %}{% endblock content %}

Далее идёт футер, в котором я использовал новый шаблонный тег - . Основное отличие тега static_placeholder от placeholder заключается в том что содержимое static_placeholder наследуется дочерними шаблонами. В данном случае нам достаточно один раз задать значение {% static_placeholder "copyright" %} на главной странице и оно автоматически будет отображаться на других страницах нашего сайта:

В самом конце мы загружаем все необходимые скрипты из папки со статикой:

{% render_block "js" %}

Теперь чтобы новый шаблон отобразился корректно, нужно поместить все зависимости в папку django_cms_project/django_cms_example/static/ , для этого просто скопируйте их из репозитория данного проекта на GitHub .

Перезагрузите сервер и обновите страницу в браузере. Если вы всё сделали правильно, то должны увидеть сайт уже в обновлённом дизайне:

Пока ещё не вся информация отображается на странице, так как мы ещё не заполнили новые плейсхолдеры. Нажмите синюю кнопку Редактировать страницу на верхней панели, а затем на кнопку Структура . Как вы видите, в структуре страницы появились 3 новых плейсхолдера: Title (у меня система перевела название этого плейсхолдера на русский язык как Заголовок ), Sub_Title и Copyright .

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

Кроме того у нас ещё есть плейсхолдер content (Содержимое ), который мы заполняли ранее. Удалите из него плагин Google Map и откройте на редактирование плагин Текст . Затем нажмите кнопку Источник в редакторе и введите произвольный текст, заключённый в теги:

Произвольный текст

Я заполнил плейсхолдеры вот так:

Отлично! Теперь нас есть полноценная первая страница сайта. Давайте для примера создадим новый шаблон и сделаем ещё одну страницу. Предположим нам нужен особенный шаблон для раздела с контактами на сайте. Для этой цели создайте в папке templates файл contacts.html с таким содержимым:

{% extends "base.html" %} {% load cms_tags %} {% block title %}{% page_attribute "page_title" %}{% endblock title %} {% block header %} {% placeholder "title" %} {% placeholder "sub_title" %} {% endblock header %} {% block content %} Контакты
{% placeholder "email" %} {% placeholder "skype" %}
{% placeholder "phone" %}
Я в социальных сетях
{% placeholder "vk" %}
{% placeholder "facebook" %}
{% placeholder "linkedin" %}
{% placeholder "github" %}
{% endblock content %}

В этом коде нет ничего нового, я просто сверстал список контактов и добавил для каждого контакта свой плейсхолдер. Ещё я для красоты переопределил блок header . Теперь нужно добавить этот шаблон в settings.py :

CMS_TEMPLATES = (## Customize this ("fullwidth.html", "Fullwidth"), ("sidebar_left.html", "Sidebar Left"), ("sidebar_right.html", "Sidebar Right"), ("contacts.html", "Contacts"))

Теперь перезагрузите сервер и создайте новую страницу, выбрав в верхней панели Страница > Создать страницу > Новая страница :

Заполните все поля в появившемся окне и нажмите кнопку Сохранить и продолжить редактирование :

В новом окне нажмите кнопку Расширенные настройки и выберите шаблон Contacts из выпадающего списка:

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

Основные поля:

  • DISPLAY NAME - отображаемое название ссылки
  • EXTERNAL LINK - используется в том случае, если ссылка идёт на внешний ресурс
  • INTERNAL LINK - позволяет ссылаться на внутренние страницы сайта
  • Link settings - в этом разделе для нас интерес представляют поля, которые позволяют сформировать ссылку для электронной почты и телефона

Как видите, сложного ничего нет. Плагин простой, удобный в использовании и довольно функциональный. Я уверен что вы без труда сможете им пользоваться.

Теперь вернёмся к нашей новой странице. После заполнения всех плейсхолдеров необходимо нажать синюю кнопку Опубликовать страницу немедленно в верхней панели инструментов. Все внесённые изменения на странице будут сохранены, сама страница опубликована и в главном меню сайта появится новый пункт Контакты . Вот что должно получиться в итоге:

У нас получился небольшой и красивый сайт, но так как данный проект демонстрационный, тут можно ещё много чего доработать. Теперь вы знаете основы работы с DjangoCMS и уже можете создать свой собственный сайт на основе данного фреймворка.

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