Компактный сервер для Django приложений. Установка Django через pip в Virtualenv. Эскизы и черновики

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

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

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

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

Установка Django CMS

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

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 , поэтому будет продолжение, где я расскажу о плагинах, сторонних дополнениях и кастомизации функционала сайта.

Описание процесса быстрой установки Django из Панели управления Plesk.

Статья устаревшая, относится к панели Plesk, которая больше не будет поддерживаться.

"Профи" (с подключенным SSH-доступом), "Плюс", "VIP", а так же во время тестового доступа по этим тарифам, и предлагает быстро создать новый проект Django. Для того чтобы это сделать необходимо:

  • Войти в Панель управления (учетные данные для доступа вы получаете сразу после .)
  • В главном меню панели управления выбрать пункт "Домены".
  • Выбрать домен, на который планируется установить Django.
  • В группе "Приложения и услуги" выбрать пункт "Веб-приложения".
  • В строке поиска ввести django, после чего начать установку.
  • Внимательно прочитать лицензионное соглашение, после согласия возможна дальнейшая установка.
  • В разделе "параметры установки" выбрать целевой каталог для установки приложения.
  • В разделе "Настройки базы данных" необходимо выбрать тип (На данный момент поддерживается MySQL и PostgreSQL), указать имя пользователя и пароль базы данных - данные параметры будут автоматически внесены в файл settings.py.
  • Далее необходимо ввести логин, адрес электронной почты и пароль администратора, данный пароль будет использован далее.
  • В разделе "Личные настройки" при установке пакета предоставляется доступ к настройкам Django для нового проекта, в частности:
    • "Имя Django проекта" - имя проекта Django, который будет создан.
    • "Имя директории с проектами Django" - имя директории где будут располагатьcя проекты django, данная директория будет располагатьcя в папке private на вашей площадке.
    • "Активировать интерфейс администратора" - при выборе данной опции django разворачивается с включенным админ-разделом, производится синхронизация базы данных, логин и пароль администратора устанавливается в значения, указанные выше.
    • "Свой virtualenv " - данная опция подразумевает создание собственной "инстанции" python, при этом вы получаете возможность устанавливать свои модули, которые могут отличаться от установленных на хостинг, при включении, дисковое пространство, занимаемое приложением, несколько увеличивается.
  • После установки данного приложения, по адресу http://имя_домена/директория_установки/ будет доступна стандартная страница установленной Django последней стабильной версии с Python 2.6.2, для дальнейших операций и выполнения стандартных действий, например, управление проектом через manage.py, необходим полный ssh доступ. Данная услуга доступна по-умолчанию для тарифных планов "Плюс" и "VIP", на тарифе "Профи" существует возможность получить полный ssh доступ, расширив тариф дополнительной опцией через систему биллинга . Если данный пакет по каким-либо причинам не удовлетворяет требованиям Вашего проекта, Вы можете создать Django-проект

    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:

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

    Какой самый удобный способ организовать все эти каталоги на машине разработки? Как вы их называете, и как вы подключаете и развертываете это на сервере?

    • проекты (все проекты, над которыми вы работаете)
    • исходные файлы (само приложение)
    • рабочая копия репозитория (я использую git)
    • виртуальная среда (я предпочитаю разместить ее рядом с проектом)
    • статический корень (для скомпилированных статических файлов)
    • медиа-корень (для загруженных медиафайлов)
    • README
    • ЛИЦЕНЗИИ
    • документы
    • эскизы
    • (пример проекта, который использует приложение, предоставленное этим проектом)
    • (в случае использования sqlite)
    • все, что вам обычно нужно для успешной работы над проектом

    Проблемы, которые я хочу решить:

    4 ответов

    Есть два типа Django-проектов, которые у меня есть в моем каталоге ~/projects/ , оба имеют немного другую структуру.:

    • Автономные сайты
    • Подключаемые приложения
    Автономный веб-сайт

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

    ~/projects/project_name/ docs/ # documentation scripts/ manage.py # installed to PATH via setup.py project_name/ # project dir (the one which django-admin.py creates) apps/ # project-specific applications accounts/ # most frequent app, with custom user model __init__.py ... settings/ # settings for different environments, see below __init__.py production.py development.py ... __init__.py # contains project version urls.py wsgi.py static/ # site-specific static files templates/ # site-specific templates tests/ # site-specific tests (mostly in-browser ones) tmp/ # excluded from git setup.py requirements.txt requirements_dev.txt pytest.ini ...

    Настройки

    Основные настройки - производственные. Другие файлы (например, staging.py , development.py) просто импортирует все из production.py и переопределяет только необходимые переменные.

    Для каждой среды существуют отдельные файлы настроек, например. производство, развитие. Я некоторые проекты, которые я тестировал (для тестировщика), (как проверка перед окончательным развертыванием) и heroku (для развертывания в heroku).

    Требования

    Я скорее задаю требования в setup.py напрямую. Только те, которые необходимы для среда разработки/тестирования У меня есть requirements_dev.txt .

    Некоторые службы (например, heroku) требуют наличия requirements.txt в корневом каталоге.

    setup.py

    Полезно при развертывании проекта с помощью setuptools . Он добавляет manage.py в PATH , поэтому я могу запустить manage.py напрямую (в любом месте).

    Приложения для конкретных проектов

    Я использовал эти приложения в каталоге project_name/apps/ и импортировал их используя относительный импорт.

    Шаблоны/статические/локальные/тестовые файлы

    Я помещал эти шаблоны и статические файлы в глобальные шаблоны/статический каталог, а не внутри каждого приложения. Эти файлы обычно редактируются людьми, которым не нужен код проекта структуры или питона вообще. Если вы являетесь разработчиком полного стека, работающим в одиночку или в небольшой команде вы можете создавать шаблоны для каждого приложения/статический каталог. Это действительно просто вопрос вкуса.

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

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

    каталог Tmp

    В корне проекта есть временная директория, исключенная из VCS. Он имел обыкновение хранить медиа/статические файлы и базу данных sqlite во время разработки. Все в tmp может быть удален в любое время без каких-либо проблем.

    Virtualenv

    Я предпочитаю virtualenvwrapper и поместить все venvs в каталог ~/.venvs но вы можете разместить его внутри tmp/ , чтобы сохранить его вместе.

    Шаблон проекта

    Я создал шаблон проекта для этой установки, django-start-template

    Развертывание

    Развертывание этого проекта выполняется следующим образом:

    Source $VENV/bin/activate export DJANGO_SETTINGS_MODULE=project_name.settings.production git pull pip install -r requirements.txt # Update database, static files, locales manage.py syncdb --noinput manage.py migrate manage.py collectstatic --noinput manage.py makemessages -a manage.py compilemessages # restart wsgi touch project_name/wsgi.py

    Вы можете использовать rsync вместо git , но все же вам нужно запустить пакет команд для обновления вашей среды.

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

    Эскизы и черновики

    Черновик шаблонов, которые я размещаю внутри глобального каталога templates/ . Я думаю, можно создать папку sketches/ в корне проекта, но еще не использовали ее.

    Подключаемое приложение

    Эти приложения обычно готовятся к публикации как открытые. Я привел пример ниже django-forme

    ~/projects/django-app/ docs/ app/ tests/ example_project/ LICENCE MANIFEST.in README.md setup.py pytest.ini tox.ini .travis.yml ...

    Название каталогов понятно (надеюсь). Я помещал тестовые файлы вне каталога приложения, но это действительно неважно. Важно предоставить README и setup.py , поэтому пакет легко устанавливается через pip .

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

    Проекты
    У меня есть основная папка в моем личном каталоге, где я просматриваю все объекты, на которых я работаю.

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

    Project_repository_folder/ .gitignore Makefile LICENSE.rst docs/ README.rst requirements.txt project_folder/ manage.py media/ app-1/ app-2/ ... app-n/ static/ templates/ project/ __init__.py settings/ __init__.py base.py dev.py local.py test.py production.py ulrs.py wsgi.py

    Репозиторий
    Git или Mercurial, по-видимому, являются самыми популярными системами управления версиями среди разработчиков Django. И самые популярные услуги хостинга для резервных копий GitHub и Bitbucket .

    Виртуальная среда
    Я использую virtualenv и virtualenvwrapper. После установки второго нужно настроить рабочий каталог. Mine находится в каталоге my/home/envs, так как это рекомендуется в руководстве по установке virtualenvwrapper. Но я не думаю, что самое главное, где оно размещено. Самое главное при работе с виртуальными средами - обновлять файл requirements.txt.

    Pip freeze -l > requirements.txt

    Статический корень
    Папка проекта

    Корень СМИ
    Папка проекта

    README
    Корень репозитория

    ЛИЦЕНЗИЯ
    Корень репозитория

    Документы
    Корень репозитория. Эти пакеты python могут помочь вам упростить вашу документацию:

    Эскизы

    Примеры

    База данных

    Мне не нравится создавать новый каталог settings/ . Я просто добавляю файлы с именем settings_dev.py и settings_production.py , поэтому мне не нужно редактировать BASE_DIR . Приведенный ниже подход увеличивает структуру по умолчанию вместо изменения.

    Mysite/ # Project conf/ locale/ en_US/ fr_FR/ it_IT/ mysite/ __init__.py settings.py settings_dev.py settings_production.py urls.py wsgi.py static/ admin/ css/ # Custom back end styles css/ # Project front end styles fonts/ images/ js/ sass/ staticfiles/ templates/ # Project templates includes/ footer.html header.html index.html myapp/ # Application core/ migrations/ __init__.py templates/ # Application templates myapp/ index.html static/ myapp/ js/ css/ images/ __init__.py admin.py apps.py forms.py models.py models_foo.py models_bar.py views.py templatetags/ # Application with custom context processors and template tags __init__.py context_processors.py templatetags/ __init__.py templatetag_extras.py gulpfile.js manage.py requirements.txt

    • Tutorial
    Введение Многие начинающие веб разработчики размышляют о том, где бы разместить свое творение. Обычно для этих целей применяются машины под управлением *NIX подобных систем. Мой выбор остановился на Raspberry PI, поскольку малинка:
    • работает под управлением полноценного Linux,
    • долгое время лежит на столе и пылится.
    Я хочу рассказать о том, как настроить сервер, работающий в сети с динамическим внешним IP адресом. Для запуска крупных проектов такое решение не годится, а для демонстрации своего портфолио и персонального применения вполне подойдет.Нам понадобятся
  • Raspberry PI модели B, B+ или Raspberry PI 2 (поскольку на платах этих моделей имеется Ethernet) с установленной Raspbian и активированным SSH сервером. О настройке можно почитать , или . Помимо Raspian для малинки существует большое количество альтернативных дистрибутивов . Тут, как говорится, «на любой вкус и цвет».
  • Рабочее Django приложение.
  • Роутер с поддержкой DDNS. Этот пункт не обязателен, поскольку DDNS можно настроить на самой малинке.
  • Я буду работать с малинкой модели B+.Подготовка На малинке установлена Raspbian 7.8.
    Для начала необходимо найти малинку в сети, чтобы подключиться к ней по ssh.
    nmap -sP 192.168.1.1/24 | grep raspberry

    В моем случае в сети две малинки, одна из которых моя с IP адресом 192.168.1.100. В некоторых сетях nmap не показывает сетевые имена устройств.


    В этом случае найти raspberry pi можно по MAC-адресу, который имеет префикс B8:27:EB.
    sudo nmap -sP -n 192.168.1.1/24 | grep -B 2 B8:27:EB


    Параметр -B для grep определяет какое количество предшествующих строк следует вывести.

    Подключаемся к малинке по ssh.
    ssh [email protected]


    Для начала разгоним малинку до 1 ГГц с помощью raspi-config .
    Устанавливаем питоновский менеджер пакетов
    sudo apt-get install python-pip

    Переходим к установке необходимых пакетов. В моем web приложении используется СУБД MySQL. В качестве Frontend и Backend используется nginx и gunicorn соответственно.
    sudo apt-get install nginx gunicorn mysql-client mysql-server python-mysqldb


    В процессе установки mysql необходимо ввести данные для root пользователя СУБД. python-mysqldb - драйвер, необходимый при работе с моделями в Django. Django установим из питоновских репозиториев.
    sudo pip install django

    На момент написания статьи актуальные версии nginx и gunicorn в репозиториях для малинки 1.2.1 и 0.14.5 соответственно. Версия MySQL для малинки 5.5. Так же для работы с Django необходимо установить SciPy .
    sudo apt-get install python-scipy

    Nginx 1.2.1 устарел. Более новый можно собрать из исходников . Свежий gunicorn можно установить из питоновских репозиториев.

    Настройка сервера Размещаем web-приложение на малинке (например в /home/pi).
    Если у Вас есть рабочие конфиги, то достаточно их скопировать в соответствующие директории:
    • для nginx /etc/nginx/sites-enabled/
    • для gunicorn /etc/gunicorn.d/
    C nginx ничего сложного нет. Я бы хотел обратить внимание на настройки для gunicorn.
    CONFIG = { "mode": "wsgi", "working_dir": "/home/pi/project", #"working_dir": "/home/pi/project/project", "user": "www-data", "group": "www-data", "python": "/usr/bin/python", "args": ("--bind=127.0.0.1:8081", "--workers=5", # 5 достаточно для малинки "--graceful-timeout=60", "--timeout=60", #"--debug", #"wsgi:application", "project.wsgi",), }

    Если working_dir (путь к файлу wsgy.py) указать "/home/pi/project/project" , а в args указать "wsgi:application" , то на малинке воркеры сначала стартуют, потом умирают без указания причины (под Ubuntu, например, gunicorn работает с обоими вариантами настроек).

    Перенос MySQL Дамп имеющейся БД можно сделать с помощью утилиты mysqldump .
    mysqldump -u root -p dbname > dbname.sql

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


    На малинке создаем базу данных. Запускаем mysql shell.
    mysql -u root -p

    Добавляем новую базу данных.
    mysql> create database dbname character set utf8 collate utf8_general_ci; mysql> grant all privileges on dbname.* to someusr@localhost identified by "somepassword";
    Восстанавливаем данные с дампа. При размере дампа в 162 Мб время восстановления составило около 10 минут.
    mysql -u root -p dbname < dbname.sql

    Следует отметить, что базы данных лучше хранить на внешнем накопителе, иначе micro SD карта может быстро придти в негодность из-за частых операций записи. Как это сделать можно почитать . Конфиг mysql расположен по пути /etc/mysql/my.cnf

    Проверка Перезапускаем nginx и gunicorn. Если все настроено верно, можно открыть главную страницу.


    Переходим к нагрузочному тестированию. Установим apache benchmark.
    sudo apt-get install apache2-utils

    Протестируем в 4 потока 1000 запросами Raspberry PI модель B+.
    ab -c 4 -n 1000 http://192.168.1.100/

    Vladislav@vladislav-N53SV:~$ ab -c 4 -n 1000 http://192.168.1.100/ This is ApacheBench, Version 2.3 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.1.100 (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Completed 1000 requests Finished 1000 requests Server Software: nginx/1.8.0 Server Hostname: 192.168.1.100 Server Port: 80 Document Path: / Document Length: 24839 bytes Concurrency Level: 4 Time taken for tests: 1309.607 seconds Complete requests: 1000 Failed requests: 0 Total transferred: 25018000 bytes HTML transferred: 24839000 bytes Requests per second: 0.76 [#/sec] (mean) Time per request: 5238.429 (mean) Time per request: 1309.607 (mean, across all concurrent requests) Transfer rate: 18.66 received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 0.1 1 1 Processing: 4924 5237 91.4 5227 6419 Waiting: 4919 5227 91.3 5217 6403 Total: 4925 5238 91.4 5228 6420 Percentage of the requests served within a certain time (ms) 50% 5228 66% 5245 75% 5255 80% 5265 90% 5296 95% 5335 98% 5382 99% 5667 100% 6420 (longest request)
    Запросы идут медленно, поскольку большую часть времени запроса занимает работа с БД. Ко мне недавно пришла Raspberry PI 2 модель B. Посмотрим на что она способна c теми же настройками и данными.
    vladislav@vladislav-N53SV:~$ ab -c 4 -n 1000 http://192.168.1.14/ This is ApacheBench, Version 2.3 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.1.14 (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Completed 1000 requests Finished 1000 requests Server Software: nginx/1.8.0 Server Hostname: 192.168.1.14 Server Port: 80 Document Path: / Document Length: 24838 bytes Concurrency Level: 4 Time taken for tests: 170.083 seconds Complete requests: 1000 Failed requests: 0 Total transferred: 25017000 bytes HTML transferred: 24838000 bytes Requests per second: 5.88 [#/sec] (mean) Time per request: 680.330 (mean) Time per request: 170.083 (mean, across all concurrent requests) Transfer rate: 143.64 received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 0.1 1 1 Processing: 569 678 104.6 650 1338 Waiting: 567 676 104.1 647 1334 Total: 569 679 104.6 651 1338 Percentage of the requests served within a certain time (ms) 50% 651 66% 682 75% 708 80% 727 90% 796 95% 890 98% 1045 99% 1138 100% 1338 (longest request)
    Raspberry PI 2 обрабатывает запросы в среднем в 6,16 раз быстрее. Разработчики малинки не обманули.

    Настройка DDNS Настроить DDNS можно на роутере или на самой малинке. Я выбираю No IP , поскольку пользуюсь им несколько лет. Рассмотрим бесплатное использование.

    Регистрация хоста

    Если у вас есть учетная запись - проходим авторизацию, иначе регистрируемся . После авторизации попадаем сюда .


    Кликаем AddHost и заполняем форму.


    Внизу кликаем кнопку AddHost
    Хост добавлен. Справа от имени хоста отображается внешний IP адрес Вашей сети.


    Настраиваем DDNS на роутере Для примера я настрою DDNS на ASUS RT-N56U с прошивкой от padavan версии 3.4.3.9-091. Открываем в страницу меню роутера
    (например 192.168.1.1). WAN->DDNS.


    Выбираем сервис no-ip.com, указываем регистрационные данные, а так же наш добавленный хост (technopark-test.ddns.net).
    Остальные параметры выставляем по собственному желанию.


    Теперь при смене внешнего IP адреса наше приложение остается доступным в сети.Настройка переадресации портов Нам нужно, чтобы при обращении к хосту малинка отдавала веб приложение. Роутер занимается перенаправлением входящих пакетов, пришедших из вне с порта X на внутренный порт Y. В меню роутера переходим WAN->Переадресация портов. Необходимо перенаправлять внешний 80 порт на 80 порт малинки. Добавим новое правило и применим изменения.

    Теперь малинка обрабатывает все приходящие пакеты на 80 порту. Проверим, введя в адресной строке браузера хост, полученный в No IP.


    Теперь наше веб приложение доступно для пользователей сети Интернет.Настраиваем DDNS на малинке Этот вариант не подходит, если малинка имеет частный IP , поскольку она будет оправлять свой локальный IP адрес на на сервис No IP. Это еще один способ узнать IP адрес малинки локальной сети. Установим DDNS клиент.
    sudo apt-get install ddclient

    Во время установки необходимо выбрать сервис. Выбираем other и вводим dynupdate.no-ip.com, протокол dyndns2, имя пользователя, пароль, интерфейс - eth0, имя хоста.


    Для проверки я выставил интервал обновления IP в 60 секунд. В файле /etc/default/ddclient необходимо выставить значение daemon_interval=«60».

    Десерт Моя малинка давно лежала на столе и пылилась, вместе с tm1638 и , выводя показания температуры и влажности в помещении и прочей информации.
    Все же мне было интересно попробовать управлять GPIO Raspberry PI из django. Я разработал простое web приложение, которое объединило мои ранние наработки. Оно позволяет посмотреть температуру и влажность, измеренные с помощью DHT11, некоторую полезную информацию, управляет 8-ми релейным модулем (который может быть использован для управления электроприборами) и отправляет текст на tm1638.

    Для управления GPIO необходимо запускать сервер с правами root. Это потенциальная уязвимость.
    Полноценное использования web приложения предполагает работу сервера без прав суперпользователя, настройку https, добавление возможности администрирования учетных записей, ведение логов, разделение доступа к управляемым устройствам, работу электроприборов по расписанию и многое другое.
    Впрочем это уже совсем другая история статья.

    Заключение Имея Raspberry PI моделей B, B+ или Raspberry PI 2, power bank , а так же «open» Ethernet jack получаем компактный сервер, который можно использовать для демонстрации своих наработок. Настройка сервера для Django приложений на Raspberry PI под управлением Raspbian мало чем отличится от любой другой сборки Linux. Пакеты в репозиториях могут быть устаревшими. Для работы с новыми версиями можно вручную собирать программы из исходников.
    Добавить метки