Являясь большим фанатом Python и фреймворка Django постоянно искал решение, как сделать разработку новых веб-проектов быстрее и удобнее.

Все, кто знаком с разработкой на Django, знают насколько неудобно строить на нем интуитивно понятную админ.панель. До мегапопулярного WordPress очень далеко, что делает порог вхождения в разработку сайтов выше, чем у PHP-фреймворков и CMS.
После долгого поиска и тестирования различных решений я нашел для себя оптимальный вариант — Wagtail CMS.

Wagtail — это полноценная CMS написанная на Django компанией Torchbox. За что им большое спасибо. Проект с открытым исходным кодом, поддерживается сообществом энтузиастов и выпускается под BSD лицензией.



Вот типичный интерфейс Wagtail:
image

В 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.
image

Отлично, теперь перейдем в админ панель 199.199.32.32:8000/admin, вводим логин и пароль пользователя которые мы создали ранее и попадаем в удобный интерфейс Wagtail CMS:
image

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

Шаг 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


После этого вы можете зайти в админ.панель и отредактировать текст на вашей стартовой странице.
Сохраните изменения и откройте опять ваш сайт. Вы увидите свой текст, примерно такого вида:
image

Для начала неплохо, но надо добавить разметку и красоту 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>


Сохраняем и снова открываем наш сайт. Должно получиться, что-то похожее на эту картинку:

image

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

Шаг 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.

Идем в админ.панель, открываем «Проводник», выбираем главную, и нажимаем «добавить дочернюю страницу», появиться следующее окно с выбором шаблонов для создаваемой страницы:
image
Выбираем «Blog Page» и заполняем страницу информацией.

Вот пример редактирования страницы блога в админ.панели wagtail:
image

Довольно удобно и быстро.

Сохраняем запись и открываем в браузере. Первая запись вашего блога готова.

Если хоть кому-то данный пост окажется полезным, то я продолжу публикацию постов на тему 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)


  1. WST
    23.06.2016 09:23

    Интересная штука, спасибо вам


  1. XenoAura
    23.06.2016 09:33

    Что в ней такого, что она требует аж 1gb памяти?


    1. alexhouse
      23.06.2016 09:37

      1 Gb нужен не для Wagtail, а чтобы без проблем работал PostgreSQL, Gunicorn, Nginx и прочее на сервере. Условие в 1 Gb памяти не обязательно, но как показывает практика это оптимальное количество для нормального проекта.


      1. Yahweh
        23.06.2016 10:23
        +1

        Да ладно, там 512Mb с головой хватит для PostgreSQL, Gunicorn, Nginx.


        1. xmaster83
          23.06.2016 16:21

          А при большом обьёме контента поиск не будет томозить если там всё через ORM ,?


          1. gelas
            24.06.2016 21:54

            нормальный регистронезависимый поиск там только через elasticsearch


            1. m1kola
              29.06.2016 20:49
              +1

              Из коробки Wagtail поддеживает два бэкенда: база данных (по умолчанию) и Elasticsearch (рекомендуемый), но вы можете написать свой бэкенд.


              Т.е. я бы перефразировал ваш коммент вот так:
              Нормальный регистронезависимый поиск из коробки там только через Elasticsearch


  1. prostofilya
    23.06.2016 10:18

    Пост действительно полезный, спасибо!


  1. Terras
    23.06.2016 11:11

    Вторая по популярности cms после Django-cms на django. Чаще всего используется буржуями для визиток и порталов. Т.е. сложные проекты на нем делать не так приятно, а вот для легкого редактирования — в самый раз.


    1. m1kola
      29.06.2016 20:58

      Не могли бы вы привести пример сложностей с которыми вы столкнулись при разработке сложных проектов? Возможно я смогу что-то посоветовать или вы натолкнете меня на мысли о том, что можно поменять в Wagtail чтобы делать проекты с Wagtail было приятнее.


  1. PTM
    23.06.2016 11:41

    Я только для блога использовал бы генератор статических сайтов.
    Есть почти все, а хостинг несравненно дешевле.


    1. utkorose
      23.06.2016 14:09
      +1

      0 рублей на Github Pages


  1. ekotov77
    23.06.2016 12:45
    +1

    По мне одна из самых простых и приятных cms для django это django-fiber.


  1. medvoodoo
    23.06.2016 17:09

    Совсем недавно на питоне 2.7 у нее были совершенно не детские проблемы с UTF-8, на третьем не пробовал. Работать в ней с русским языком было совершенно невозможно, куча ошибок в админке.


    1. alexhouse
      24.06.2016 02:26
      +1

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


      1. m1kola
        29.06.2016 21:34

        @alexhouse, спасибо за статью и за комменты. Будем стараться держать перевод на русский около 100%. Будем благодарны за помощь с переводом ;)


        @medvoodoo, да, баги с юникодом периодически находим, но я их помню не так много. Все баги стараемся покрывать тестами. Тесты запускаем на разных версиях питона.


        Если не затруднит, пожалуйста, дайте больше деталей о проблеме через задачу на Github или прямо тут.


  1. gelas
    24.06.2016 21:55
    +1

    Самое клевое в wagtail — это StreamField, фактически визуальный редактор json'a.


  1. vermus
    29.06.2016 10:59

    Крутое демо:

    git 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
    


    Я хочу просто посмотреть его в работе, а не ставить варганты, СУБД и прочее… Есть ли ссылка на рабочий вариант?


    1. m1kola
      29.06.2016 21:21

      wagtaildemo как раз и использует Vagrant для того чтобы вам не пришлось ставить СУБД и прочее самому. Для вас он сделает следующее:


      • Создаст виртуалку
      • Поставит туда postgresql
      • Поставит python-зависимости
      • Создаст базу
      • Выполнит миграции
      • Накатит тестовый контент

      Вам нужно будет только запустить Django-команду ./manage.py runserver 0.0.0.0:8000


      Другой вариант — задеплоить wagtaildemo на Heroku.


      Если вы хотите найти примеры сайтов (а не пощупать админку), то их можно найти на madewithwagtail.org.


      1. vermus
        29.06.2016 22:07

        Спасибо за ссылку на примеры сайтов. Каюсь, не работал с Vargant толком (но с ним опять таки надо разбираться). Жаль нет демо сайта+ админки.


        1. m1kola
          29.06.2016 22:48

          Пожалуйста!


          С Vagrant нужно разбираться, когда вы собираетесь писать свою конфигурацию. Тут конфигурация уже есть и нужно просто запустить vagrant up. А, ну и, очевидно, нужно установить сам Vagrant и VirtualBox.


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