Django CMS is one of the content management systems that is geared towards working with Django framework based web applications. It is perhaps the most popular one out of almost three dozen other options available today. Being a mature, production ready system trusted by some important brands from around the world and having a professional company backing its development surely makes it an attractive choice for projects.
In this DigitalOcean article, we will walk you through installing Django CMS on a Debian 7/Ubuntu 13 VPS, ready to be configured and used. If you are interested in using Django [CMS] but do not have much experience with the framework or the Python language itself, do not worry: Django CMS comes with a relatively straight forward and quite rich documentation for development which will be more than enough to get you going after completing this tutorial. You can access the latest version by clicking here.
pip is a package manager which will help us to install the software packages (tools, libraries, applications et alia) that we need in a very easy fashion.
A dependency of pip, setuptools library builds on the functionality of Python’s standard software distribution utilities toolset distutils.
Many things are extremely simple to achieve in Python and installing packages and applications is no exception. However, a significant amount of these packages come depending on others as well. Upon installation, together with the rest, they become available system-wide: any Python application can link to those libraries and use them.
In certain circumstances, this might cause serious headache with an already configured and stable application ceasing to work due to some dependency issue. As anything you install or remove affects the entire system altogether, the wrong version of a library or a module can break everything. At another time, you might start developing a new project and find yourself in need of a clean working environment.
This is what the virtualenv tool is there for and exactly why we will make use of it: to isolate our Django CMS application repository and its complex dependencies from the rest of the system, allowing us to have everything in order, easing maintenance at the same time.
Please Note: We will be using a freshly created VPS for this article. This prevents any possible software related or security issues from the past installations.
First, we need to bring our operating system up to date. Let’s start with updating the software repository list followed by upgrading the installed tools on our machine to more recent versions:
aptitude update
aptitude upgrade
We can now continue with installing other software tools and libraries that we will need along the way.
Here is what we will need:
python-dev: This package extends the default Python installation on our system.
libjpeg-dev/libpng-dev: These libraries will be needed for image processing with Python imaging library.
libpq-dev: The libpq’s (PostgreSQL) development version, which we will need further later on in the tutorial.
To download and install, run the following command:
aptitude install libpq-dev python-dev libjpeg-dev libpng-dev
Everything we need runs on Python. Default Debian 7 installation comes with Python version
2.7
. As this suits our requirements, we can continue with installing pip, which we need for the virtualenv (and other packages’) installation.
Before getting pip, we first need to install its dependency: setuptools.
We are going to securely download the setup files using a tool called curl. These setup files will not only allow us to have the installation process automated, but also ensures that we have the latest stable versions running on our system. curl here will verify the SSL certificates from the source and pass the data to the Python interpreter.
Execute the following command:
$ curl https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py | python -
This will install it system-wide.
We can now install and set up pip on our system.
Let’s use curl again to have it securely downloaded and installed. Run the following:
$ curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python -
This will install it system-wide.
By default, pip installs its files under /usr/local/bin
location. We need to append it to our PATH
so that we will be able to run it with calling pip command directly.
Let’s have it updated:
export PATH="/usr/local/bin:$PATH"
As we have pip the package manager, all installations from now on are as easy as pip install package-name
. However, as we want the latest stable release of virtualenv, we are going to provide pip with the address.
Run the following to have pip install virtualenv:
pip install https://github.com/pypa/virtualenv/tarball/1.9.X
This will install it system-wide.
In case you were wondering, the standard way of installing would have been:
pip install virtualenv
This would also install it system-wide.
All the tools we need are ready and we can begin preparing the virtual environment where our Django CMS project is going to reside.
Let’s start with initiating a venv (virtual environment) called “django_cms” using virtualenv and go to the project’s folder:
virtualenv django_cms
cd django_cms
We chose “django_cms” as the project repository’s folder name. You can change it as you wish. Keep in mind that choosing an unrelated name could cause trouble in the future with maintenance.
Upon creating a virtualenv, you need to activate it in order to use it.
source bin/activate
You can learn more about virtualenv’s activation by clicking here.
Upon activation, in order to deactivate, simply run the command
deactivate
when needed.
One of the dependencies that we need to have is called Python Imaging Library (PIL). Together with some other libraries we have installed earlier, PIL is used by Django [CMS] to process images.
That being said, we will abstain from PIL and use a more accommodating fork of PIL called pillow. This package is setuptools compatible and automatically solves several issues that would arise if we were to try and use pil inside a venv.
Run the following to have pillow downloaded and installed:
django_cms$ pip install pillow
As we have our venv activated, this will not be a system-wide installation.
Django [CMS] allows you to choose several database engines to power your application. PostgreSQL, MySQL, Oracle and SQLite are all currently supported. As recommended by Django project, we are going to opt for PostgreSQL and install necessary libraries and drivers that will allow us to use it as the backend of our application.
The PostgreSQL database adapter which is used by Django is called psycopg2. It needs libpq-dev library installed and we have installed it at the beginning. Therefore, we can continue with executing the following command to install psycopg2 in our venv:
django_cms$ pip install psycopg2
As we have our venv activated, this will not be a system-wide installation.
For more on psycopg2, you can visit http://initd.org/psycopg/docs/faq.html.
Please note: These commands ready PostgreSQL for Django but does not give you a fully configured installation. If you choose to work with PostgreSQL and you need further instructions on Django, you may wish to visit the following DigitalOcean tutorial on the exact subject by clicking here.
Below we are using an SQLite database. You should also modify that setting to work with your PostgreSQL installation if you decide to use it.
Django CMS comes with a number of other dependencies we yet need to install. However, thanks to pip, we can have the remaining automatically installed and set up with the Django CMS package: django-cms.
Simply run the following to conclude the installations:
django_cms$ pip install django-cms
As we have our venv activated, this will not be a system-wide installation.
We now have everything installed: Django, django-classy-tags, south, html5lib, django-mptt, django-sekizai.
To learn more about these packages click here.
Creating a Django CMS project consists of two parts. First, we will start a regular Django project in our virtual environment and then continue with setting it up to have it working as Django CMS.
Let’s begin with creating the Django project. We will name it dcms, you can choose it to suit your needs.
Simply run the following:
django_cms$ django-admin.py startproject dcms
django_cms$ cd dcms
You will see that our project is created. In order to test the installation before continuing with the configuration part, let’s run the following to start a simple development server which we can access from the outside:
django_cms$ python manage.py runserver 0.0.0.0:8000
Visit the URL from your browser, replacing 0.0.0.0
with your server’s IP address.
We can now follow the instructions listed at Django CMS Introductory Tutorial to finalize everything.
Most of the configurations for Django CMS takes place inside the settings.py
file located inside the project folder.
Open it with your favourite editor. In this tutorial, we will be using nano
.
django_cms$ nano dcms/settings.py
Add the following lines to the top of the file:
# -*- coding: utf-8 -*-
import os
gettext = lambda s: s
PROJECT_PATH = os.path.split(os.path.abspath(os.path.dirname(__file__)))[0]
To begin with the first batch of settings, scroll down the file and find INSTALLED_APPS section. Here, to the end of the currently existing list of modules, we are going to append the names of a few more which we’ve already installed, including the Django CMS module itself.
As stated on the Django CMS documentation:
Add the following apps to your INSTALLED_APPS. This includes django CMS itself as well as its dependenices and other highly recommended applications/libraries:
'cms', # django CMS itself
'mptt', # utilities for implementing a modified pre-order traversal tree
'menus', # helper for model independent hierarchical website navigation
'south', # intelligent schema and data migrations
'sekizai', # for javascript and css management
Please note: Before moving on, make sure to uncomment django.contrib.admin
from the list as well. That module is needed for the setup procedure.
Next, let’s find MIDDLEWARE_CLASSES
and add the following to the bottom of the list:
'cms.middleware.page.CurrentPageMiddleware',
'cms.middleware.user.CurrentUserMiddleware',
'cms.middleware.toolbar.ToolbarMiddleware',
'cms.middleware.language.LanguageCookieMiddleware',
Afterwards your MIDDLEWARE_CLASSES should look similar to:
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'cms.middleware.page.CurrentPageMiddleware',
'cms.middleware.user.CurrentUserMiddleware',
'cms.middleware.toolbar.ToolbarMiddleware',
'cms.middleware.language.LanguageCookieMiddleware',
)
As stated in the Django CMS documentation, we need to add a missing piece of settings code block to the file. It does not exist in settings.py
. Copy-and-paste the block to a free location in the file:
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.i18n',
'django.core.context_processors.request',
'django.core.context_processors.media',
'django.core.context_processors.static',
'cms.context_processors.media',
'sekizai.context_processors.sekizai',
)
Now let’s find and modify the STATIC_ROOT
and MEDIA_ROOT
directives similar to the following:
MEDIA_ROOT = os.path.join(PROJECT_PATH, "media")
MEDIA_URL = "/media/"
STATIC_ROOT = os.path.join(PROJECT_PATH, "static")
STATIC_URL = "/static/"
Continue with modifying the TEMPLATE_DIRS
directive to:
TEMPLATE_DIRS = (
os.path.join(PROJECT_PATH, "templates"),
)
Django CMS requires definition of at least one template which needs to be set under CMS_TEMPLATES
. Add the following code block to the file, amending it as necessary to suit your needs:
CMS_TEMPLATES = (
('template_1.html', 'Template One'),
)
We need to set the translation languages as well. Add the following code block:
LANGUAGES = [
('en-us', 'English'),
]
Finally let’s define a database engine. You can modify the DATABASES setting to work with PostgreSQL as shown or use the following to have SQLite database set up temporarily:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(PROJECT_PATH, 'database.sqlite'),
}
}
We are done with the settings.py
. We can save and close it. (Press CTRL+X and type Y to save and close).
We need to define routes for our project.
We will do this by editing urls.py file:
django_cms$ nano dcms/urls.py
Replace the document with the following code snippet:
from django.conf.urls.defaults import *
from django.conf.urls.i18n import i18n_patterns
from django.contrib import admin
from django.conf import settings
admin.autodiscover()
urlpatterns = i18n_patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^', include('cms.urls')),
)
if settings.DEBUG:
urlpatterns += patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
url(r'', include('django.contrib.staticfiles.urls')),
) + urlpatterns
Please note that the last conditional created in the above snippet slightly differs from the Django CMS introductory settings, whereby
urlpatterns = patterns(
is replaced withurlpatterns += patterns(
to fix the problem of overridingurlpatterns
set above.
Again press CTRL+X and type Y to save and close.
We will continue with preparing templates.
Create the templates folder:
django_cms$ mkdir templates
Create an exemplary base template to extend others to come:
django_cms$ nano templates/base.html
And fill it with the below code snippet:
{% load cms_tags sekizai_tags %}
<html>
<head>
{% render_block "css" %}
</head>
<body>
{% cms_toolbar %}
{% placeholder base_content %}
{% block base_content %}{% endblock %}
{% render_block "js" %}
</body>
</html>
Let’s save and close and continue with creating our first template: template_1.html
based on base.html
.
django_cms$ nano templates/template_1.html
Fill this one with the following short snippet:
{% extends "base.html" %}
{% load cms_tags %}
{% block base_content %}
{% placeholder template_1_content %}
{% endblock %}
Let’s save and close this one as well.
Execute the following commands to synchronise database according to our settings:
django_cms$ python manage.py syncdb --all
django_cms$ python manage.py migrate --fake
To finish everything, we should check if we set it all correctly using cms check:
django_cms$ python manage.py cms check
If you see “Installation okay”, it means everything is fine and we can try it on the test server before continuing with building on our Django CMS project.
Let’s run the server again:
django_cms$ python manage.py runserver 0.0.0.0:8000
To see the Django CMS welcome screen go to:
http://your_servers_ip_addr:8000/en-us
To use the admin panel go to:
http://your_servers_ip:8000/en-us/admin
You will need to login with the user you have created during database synchronization; you can continue customizing your CMS from there.
For further instructions, tutorials and documentation you can visit http://docs.django-cms.org/en/2.4.2/. To get more support on Django CMS, you can visit the support page located at https://www.django-cms.org/en/support/.
<div class=“author”>Submitted by: <a href=“https://twitter.com/ostezer”>O.S. Tezer</div>
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Instead of downloading all the packages from around the internet, you can install python-setuptools, python-pip and python-virtualenv using aptitude.
How can i move this from myserverip:8000 to myserverip?
raise ImproperlyConfigured(‘ImportError %s: %s’ % (app, e.args[0])) django.core.exceptions.ImproperlyConfigured: ImportError django.contrib.sitesdjango.contrib.messages: No module named sitesdjango.contrib.messages
i get this error when i run python manage.py syncdb --all:(
i found it very useful till this point but got stuck here and have no idea what to do:(
It’s wonderfool this tutorial!!
I just had a problem whan i was TO CREATE A TEMPLATES FOLDER, it’s was not on the django-cms#. It must be in django-cms/dcms# directory
Thanks a lot for your work
Holy shit man, nice tutorial.
Never had a VPS before, minor experience in Linux, Python and Django. Got it set up with just a few hickups, nothing too bad :-) Could not have done it without you!
Great thanks!
Hello ostezer,
Simple and straight forward tutorial for a Cut-Paste beginner ;) Top . Looking forward maybe a tutorial how to upgrade a Dango-CMS from version 2 till 3 ;)
Thank you *mkoistinen, great to hear your thoughts!
It has been a while but I went over everything again and you are absolutely right. It can cause confusions and lead astray.
Hopefully we will have the article updated soon with your suggestion.
If you have some experience (especially production-level) that you could share regarding the matter (i.e. i18n / naming convention issues and DCMS), I’d be very interested to hear them.
Cheers!
Great to see some dcms love! Nice, thorough job too!
I recommend that you stick with one language code scheme. Either the 2-letter one like ‘en’, or the hyphenated pair one: ‘en-us’. Don’t mix them, you’re inviting trouble. =)