Before continuing, you’ll want to be familiar with part one.

It’s time to get django-cms setup. A lot of this is boilerplate stuff, and if you’re familiar with django-cms, you’ll have done this many times before:

Add these lines to the example/settings.py file

import os
gettext = lambda s: s
PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))

Modify settings.INSTALLED_APPS, so it’s something like this.

INSTALLED_APPS = (
    'cms',
    'mptt',
    'menus',
    'south',
    'sekizai',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.sites',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
)

Add the correct middleware and context processors to settings.py:

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.doc.XViewMiddleware',
    'django.middleware.common.CommonMiddleware',
    'cms.middleware.page.CurrentPageMiddleware',
    'cms.middleware.user.CurrentUserMiddleware',
    'cms.middleware.toolbar.ToolbarMiddleware',
    'cms.middleware.language.LanguageCookieMiddleware',
)
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 we need to add a template, as follows:

$ mkdir example/templates
$ touch templates/main.html

Register the template in settings.

TEMPLATE_DIRS = (
    os.path.join(PROJECT_PATH, "templates"),
)

CMS_TEMPLATES = (
    ('main.html', 'Main Template'),
)

Define your language, also in settings:

LANGUAGES = [
    ('en', 'English'),
]

Now let’s configure our example.urls. We’ll enable the admin, and add cms.urls.

admin.autodiscover()

...

urlpatterns = 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

We need to put some markup in templates/main.html. {% raw %} {% load cms_tags sekizai_tags %} {% render_block “css” %} {% cms_toolbar %} {% placeholder base_content %} {% block base_content %}{% endblock %} {% render_block “js” %} {% endraw %}

Before our next deployment, we should setup the database. The following will provision a small Postgres database:

(venv)$ heroku addons:add heroku-postgresql
Adding heroku-postgresql on farm-django-cms-test... done, v9 (free)
Attached as HEROKU_POSTGRESQL_OLIVE_URL
Database has been created and is available
 ! This database is empty. If upgrading, you can transfer
 ! data from another database with pgbackups:restore.
Use `heroku addons:docs heroku-postgresql` to view documentation.

Now, we’ll deploy, and setup the database:

$ heroku