Все, кто знаком с разработкой на Django, знают насколько неудобно строить на нем интуитивно понятную админ.панель. До мегапопулярного WordPress очень далеко, что делает порог вхождения в разработку сайтов выше, чем у PHP-фреймворков и CMS.
После долгого поиска и тестирования различных решений я нашел для себя оптимальный вариант — Wagtail CMS.
Wagtail — это полноценная CMS написанная на Django компанией Torchbox. За что им большое спасибо. Проект с открытым исходным кодом, поддерживается сообществом энтузиастов и выпускается под BSD лицензией.
Вот типичный интерфейс Wagtail:
В wagtail очень удобно работать с контентом, создавать новые публикации, разделы, работать с изображениями. Внутри этого проекта много интересных технологий. Но сегодня не об этом.
Расскажу пример по быстрому запуску простого блога для новичков в Django разработке, с учетом многих трудностей, которые могут поджидать на пути.
Нам понадобится:
1. VPS минимум с 1gb памяти
2. Базовое знакомство с django
3. Навыки в удаленной настройке Ubuntu
Шаг 1:
Вы запустили VPS сервер для разработки. Используйте Putty для удаленного подключения по SSH.
Настройка проводиться на сервере с ОС Ubuntu 14.04.
— Логинимся и начинаем базовую настройку:
sudo apt-get update
sudo apt-get upgrade
Как правило, на сервере уже стоит Python 2 и 3 версии. Проверяем следующими командами:
Python -V
Python3 -V
Для проекта будем использовать Python 3, так как с ним лучше работает Pillow и некоторые библиотеки, которые нам понадобятся.
Если каким-то образом у вас на сервере не оказалось python3, то ставим его командой:
sudo apt-get install python3
Так же нам потребуется python3-setuptools и python3-dev:
sudo apt-get install python3-setuptools
sudo apt-get install python3-dev
Учитывая, что все ставиться на чистую систему поставим PIP (чтобы поставить свежую версию «8.1.2» лучше делать это через easy_install3):
sudo easy_install3 pip
Проверить версию PIP можно командой:
pip -V
Если версия не самая свежая, то обновляем pip командой:
sudo pip install --upgrade pip
Чтобы в дальнейшем у нас не выпадало различных ошибок при установке Wagtail, сразу ставим все необходимые библиотеки для Pillow:
sudo apt-get install libtiff5-dev libjpeg8-dev zlib1g-dev libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python-tk
Теперь нам потребуется виртуальное окружение для проекта, ставим virtualenv
sudo pip3 install virtualenv
Создаем виртуалку:
virtualenv /opt/myenv
Идем в папку /opt/myenv и запускаем виртуальную среду:
source bin/activate
Вы должны увидеть строку с названием (myenv), означающую, что виртуалка запущена:
(myenv) alex@local.develop.server:/opt/myenv$
Шаг 2: Предварительная настройка сделана, переходим к установке Wagtail CMS и настройке базы данных:
1. ставим Wagtail и Gunicorn:
sudo pip3 install wagtail gunicorn
2. Создаем наш будущий блог командой
wagtail start mysite
3. Перейдем в папку блога (mysite) и установим все зависимости для проекта из файла requirements.txt
cd mysite
pip install -r requirements.txt
4. На данном этапе вы можете провести миграции и сразу запустить тестовый сервер вашего будущего блога. Но так как мы планируем сделать все правильно, то наш блог будет работать на PostgreSQL (Для django можно использовать разные базы данных, в том числе MySQL, PostgreSQL, Oracle DB и т.д). Так что проводим настройку базы данных:
sudo apt-get install libpq-dev
sudo apt-get install postgresql postgresql-contrib
5. На данный момент у вас уже запущен postgresql на порту 5432. Но чтобы база данных могла взаимодействовать с Wagtail нужно поставить psycopg2:
pip install psycopg2
6. Теперь надо создать саму базу данных для проекта, для этого зайдем под пользователем postgres и проведем некоторые дополнительные настройки:
sudo su – postgres
createdb myblog
7. Так как postgresql создает пользователя не спрашивая вас про пароль, нам надо назначит ему пароль через psql:
psql
Теперь вы можете выполнить команду смены пароля:
\password postgres
Выходим из psql и закрываем сеанс под пользователем postgres:
\q
exit
Проверьте, что вы еще в виртуально среде, если нет то опять активируйте виртуалку.
8. Теперь нам надо настроить Wagtail на взаимодействие c postgresql, для этого идем в base.py:
cd /opt/myenv/mysite/mysite/settings/
nano base.py
Открывается файл настроек, нам нужна запись DATABASES. Удаляем, то что есть и ставим туда следующее:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', # указываем, что база данных postgresql
'NAME': 'myblog', # Название вашей базы данных
'USER': 'postgres',
'PASSWORD': '******',
'HOST': 'localhost',
'PORT': '',
}
}
Кстати, в wagtail есть русский язык, так что можете заодно в настройках поправить параметр LANGUAGE_CODE.
LANGUAGE_CODE = 'ru-ru'
Собственно, мы провели все необходимые настройки, и теперь можно запускать миграции.
Шаг 3. Первый запуск
Перейдите в корневую папку вашего блога (cd /opt/myenv/mysite/) и начните вашу первую миграцию данных в данном проекте:
python manage.py migrate
Теперь создайте пользователя под которым вы будете заходить в админ.панель Wagtail:
python manage.py createsuperuser
Введите имя (например admin), пароль и почту.
Проверяем, что все работает:
python manage.py runserver 0.0.0.0:8000
Перейдем в браузере по ip адресу вашего VPS на 8000 порт (пример 199.199.32.32:8000) и увидим стартовую страницу wagtail.
Отлично, теперь перейдем в админ панель 199.199.32.32:8000/admin, вводим логин и пароль пользователя которые мы создали ранее и попадаем в удобный интерфейс Wagtail CMS:
Пока что наш сайт ничего не умеет, но скоро мы научим его всему необходимому для блога.
Шаг 4. Настройка стартовой страницы сайта
За главную страницу отвечает приложение «home» которое запускается из коробки. Чтобы стартовая страница была такой как вам надо внесем некоторые изменения в код.
Структура вашего сайта имеет такой вид:
mysite/
home/
migrations/
__init__.py
0001_initial.py
0002_create_homepage.py
templates/
home/
home_page.html
__init__.py
models.py
search/
templates/
search/
search.html
__init__.py
views.py
mysite/
settings/
__init__.py
base.py
dev.py
production.py
static/
css/
mysite.css
js/
mysite.js
templates/
404.html
500.html
base.html
__init__.py
urls.py
wsgi.py
manage.py
requirements.txt
Отредактируйте файл «home/models.py» следующим образом:
from __future__ import unicode_literals
from django.db import models
from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailadmin.edit_handlers import FieldPanel
class HomePage(Page):
body = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('body', classname="full")
]
Также отредактируйте файл home/templates/home/home_page.html:
{% extends "base.html" %}
{% load wagtailcore_tags %}
{% block body_class %} template-homepage {% endblock %}
{% block content %}
{{ page.body | richtext }}
{% endblock %}
Теперь, чтобы новые изменения заработали, проведите миграции:
python manage.py makemigrations
python manage.py migrate
После этого вы можете зайти в админ.панель и отредактировать текст на вашей стартовой странице.
Сохраните изменения и откройте опять ваш сайт. Вы увидите свой текст, примерно такого вида:
Для начала неплохо, но надо добавить разметку и красоту css.
За базовый шаблон отвечает файл «base.html» расположенный в mysite/settings/base.py;
За css отвечает «mysite.css» расположенный в mysite/static/css/mysite.css;
За js отвечает «mysite.js» расположенный в mysite/static/js/mysite.js;
Я поклонник materializecss и для нашего сайта мы возьмем у них шаблон и библиотеки.
Смотреть тут http://materializecss.com/getting-started.html
Вносим следующие изменения в base.html:
{% load static wagtailuserbar %}
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>{% block title %}{% if self.seo_title %}{{ self.seo_title }}{% else %}{{ self.title }}{% endif %}{% endblock %}{% block title_suffix %}{% endblock %}</title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
{# Global stylesheets #}
<link rel="stylesheet" type="text/css" href="{% static 'css/mysite.css' %}">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.6/css/materialize.min.css">
{% block extra_css %}
{# Override this in templates to add extra stylesheets #}
{% endblock %}
</head>
<body class="{% block body_class %}{% endblock %}">
<nav class="light-blue lighten-1" role="navigation">
<div class="nav-wrapper container"><a id="logo-container" href="#" class="brand-logo">Logo</a>
<ul class="right hide-on-med-and-down">
<li><a href="#">Navbar Link</a></li>
</ul>
<ul id="nav-mobile" class="side-nav">
<li><a href="#">Navbar Link</a></li>
</ul>
<a href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a>
</div>
</nav>
{% wagtailuserbar %}
<div class="container">
{% block content %}{% endblock %}
</div>
<footer class="page-footer orange">
<div class="container">
<div class="row">
<div class="col l6 s12">
<h5 class="white-text">Company Bio</h5>
<p class="grey-text text-lighten-4">We are a team of college students working on this project like it's our full time job. Any amount would help support and continue development on this project and is greatly appreciated.</p>
</div>
<div class="col l3 s12">
<h5 class="white-text">Settings</h5>
<ul>
<li><a class="white-text" href="#!">Link 1</a></li>
<li><a class="white-text" href="#!">Link 2</a></li>
<li><a class="white-text" href="#!">Link 3</a></li>
<li><a class="white-text" href="#!">Link 4</a></li>
</ul>
</div>
<div class="col l3 s12">
<h5 class="white-text">Connect</h5>
<ul>
<li><a class="white-text" href="#!">Link 1</a></li>
<li><a class="white-text" href="#!">Link 2</a></li>
<li><a class="white-text" href="#!">Link 3</a></li>
<li><a class="white-text" href="#!">Link 4</a></li>
</ul>
</div>
</div>
</div>
<div class="footer-copyright">
<div class="container">
Made by <a class="orange-text text-lighten-3" href="http://materializecss.com">Materialize</a>
</div>
</div>
</footer>
<!-- Scripts-->
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.6/js/materialize.min.js"></script>
{# Global javascript #}
<script type="text/javascript" src="{% static 'js/mysite.js' %}"></script>
{% block extra_js %}
{# Override this in templates to add extra javascript #}
{% endblock %}
</body>
</html>
Сохраняем и снова открываем наш сайт. Должно получиться, что-то похожее на эту картинку:
Уже лучше. Теперь нам надо создать блог, ради которого все и затевалось.
Шаг 5. Создание блога.
Идем опять в корень нашего проекта и выполняем следующую команду:
python manage.py startapp blog
После этого добавьте новое приложение «blog» в INSTALLED_APPS в mysite/settings/base.py.
Для каждой записи нашего блога будут стандартные поля — заголовок, дата, картинка, введение и основной текст. Чтобы все это работало внесите следующие изменения в «blog/models.py»
from django.db import models
from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailadmin.edit_handlers import FieldPanel
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
from wagtail.wagtailsearch import index
class BlogPage(Page):
main_image = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+'
)
date = models.DateField("Post date")
intro = models.CharField(max_length=250)
body = RichTextField(blank=True)
search_fields = Page.search_fields + [
index.SearchField('intro'),
index.SearchField('body'),
]
content_panels = Page.content_panels + [
FieldPanel('date'),
ImageChooserPanel('main_image'),
FieldPanel('intro'),
FieldPanel('body'),
]
Теперь создайте саму страницу, на которую все это будет выводиться в blog/templates/blog/blog_page.html:
{% extends "base.html" %}
{% load wagtailcore_tags wagtailimages_tags %}
{% block body_class %}template-blogpage{% endblock %}
{% block content %}
{{ page.title }}
{{ page.date }}
{% if page.main_image %}
{% image page.main_image width-500 %}
{% endif %}
{{ page.intro }}
{{ page.body|richtext }}
{% endblock %}
Пока что ничего не работает, поэтому выполняем команды
python manage.py makemigrations
python manage.py migrate
Теперь можно создать первую запись в нашем блоге, через удобный интерфейс wagtail.
Идем в админ.панель, открываем «Проводник», выбираем главную, и нажимаем «добавить дочернюю страницу», появиться следующее окно с выбором шаблонов для создаваемой страницы:
Выбираем «Blog Page» и заполняем страницу информацией.
Вот пример редактирования страницы блога в админ.панели wagtail:
Довольно удобно и быстро.
Сохраняем запись и открываем в браузере. Первая запись вашего блога готова.
Если хоть кому-то данный пост окажется полезным, то я продолжу публикацию постов на тему wagtail, в которой расскажу подробнее про различные возможности данной CMS.
Для всех заинтересовавшихся Wagtail CMS:
Официальный сайт https://wagtail.io/
Гитхаб проекта https://github.com/torchbox/wagtail/
Документация http://docs.wagtail.io/en/latest/index.html
Демосайт для изучения http://docs.wagtail.io/en/latest/getting_started/demo_site.html
Группа поддержки пользователей https://groups.google.com/forum/#!forum/wagtail
Комментарии (21)
XenoAura
23.06.2016 09:33Что в ней такого, что она требует аж 1gb памяти?
alexhouse
23.06.2016 09:371 Gb нужен не для Wagtail, а чтобы без проблем работал PostgreSQL, Gunicorn, Nginx и прочее на сервере. Условие в 1 Gb памяти не обязательно, но как показывает практика это оптимальное количество для нормального проекта.
Yahweh
23.06.2016 10:23+1Да ладно, там 512Mb с головой хватит для PostgreSQL, Gunicorn, Nginx.
xmaster83
23.06.2016 16:21А при большом обьёме контента поиск не будет томозить если там всё через ORM ,?
gelas
24.06.2016 21:54нормальный регистронезависимый поиск там только через elasticsearch
m1kola
29.06.2016 20:49+1Из коробки Wagtail поддеживает два бэкенда: база данных (по умолчанию) и Elasticsearch (рекомендуемый), но вы можете написать свой бэкенд.
Т.е. я бы перефразировал ваш коммент вот так:
Нормальный регистронезависимый поиск из коробки там только через Elasticsearch
Terras
23.06.2016 11:11Вторая по популярности cms после Django-cms на django. Чаще всего используется буржуями для визиток и порталов. Т.е. сложные проекты на нем делать не так приятно, а вот для легкого редактирования — в самый раз.
m1kola
29.06.2016 20:58Не могли бы вы привести пример сложностей с которыми вы столкнулись при разработке сложных проектов? Возможно я смогу что-то посоветовать или вы натолкнете меня на мысли о том, что можно поменять в Wagtail чтобы делать проекты с Wagtail было приятнее.
medvoodoo
23.06.2016 17:09Совсем недавно на питоне 2.7 у нее были совершенно не детские проблемы с UTF-8, на третьем не пробовал. Работать в ней с русским языком было совершенно невозможно, куча ошибок в админке.
alexhouse
24.06.2016 02:26+1Недавно выпустили версию 1.5.2, там многие ошибки пофиксили. По поводу русского языка были проблемы, но последние версии уже идут с нормальной локализацией. Название блоков из кода подписываю кириллицей, и все отлично показывает. В следующем посте напишу про свой опыт работы с админкой wagtail.
m1kola
29.06.2016 21:34@alexhouse, спасибо за статью и за комменты. Будем стараться держать перевод на русский около 100%. Будем благодарны за помощь с переводом ;)
@medvoodoo, да, баги с юникодом периодически находим, но я их помню не так много. Все баги стараемся покрывать тестами. Тесты запускаем на разных версиях питона.
Если не затруднит, пожалуйста, дайте больше деталей о проблеме через задачу на Github или прямо тут.
gelas
24.06.2016 21:55+1Самое клевое в wagtail — это StreamField, фактически визуальный редактор json'a.
vermus
29.06.2016 10:59git clone https://github.com/torchbox/wagtaildemo.git cd wagtaildemo vagrant up vagrant ssh (then, within the SSH session:) ./manage.py runserver 0.0.0.0:8000
Я хочу просто посмотреть его в работе, а не ставить варганты, СУБД и прочее… Есть ли ссылка на рабочий вариант?m1kola
29.06.2016 21:21wagtaildemo как раз и использует Vagrant для того чтобы вам не пришлось ставить СУБД и прочее самому. Для вас он сделает следующее:
- Создаст виртуалку
- Поставит туда postgresql
- Поставит python-зависимости
- Создаст базу
- Выполнит миграции
- Накатит тестовый контент
Вам нужно будет только запустить Django-команду
./manage.py runserver 0.0.0.0:8000
Другой вариант — задеплоить wagtaildemo на Heroku.
Если вы хотите найти примеры сайтов (а не пощупать админку), то их можно найти на madewithwagtail.org.
vermus
29.06.2016 22:07Спасибо за ссылку на примеры сайтов. Каюсь, не работал с Vargant толком (но с ним опять таки надо разбираться). Жаль нет демо сайта+ админки.
m1kola
29.06.2016 22:48Пожалуйста!
С Vagrant нужно разбираться, когда вы собираетесь писать свою конфигурацию. Тут конфигурация уже есть и нужно просто запустить
vagrant up
. А, ну и, очевидно, нужно установить сам Vagrant и VirtualBox.
Демо инсталляция, конечно, все намного упростила бы :) Есть довольно большая вероятность, что она появится в ближайшее время.
WST
Интересная штука, спасибо вам