Django under the hood: Django CMS and the ORM - Iacopo Spalletti

Tags: django, djangocon

(One of my summaries of a talk at the 2015 django under the hood conference).

Iacopo Spalletti is one of the core developers of django CMS. Django CMS was invited to give a talk because it is a big Django application. So it can tell us what’s the good, the bad and the ugly about Django from their perspective.

Django CMS is a good django citizen. It integrates with other django apps. It provides features to other applications. It glues applications together. It handles unstructured content using “pages”.

Django is upgradable. It takes some work, but it is doable and not very painful. Similarly django CMS.

The basis of django CMS is the Page and a tree hierarchy in which those pages are placed. And of course a template to render it. Django CMS is multilingual at the core, so everything is translatable. A title is a separate Title object. Similarly the actual content. And so on.

Django CMS uses a lot of django features. Of the 14k lines, 3k are in the admin and 2k in the models, for instance. And 1k lines in the template tags: that is a lot. It is a central part of django CMS to work with templates. Tags such as {% cms_toolbar %} to inject the cms toolbar. And {% placeholder 'some-thing' %} for injecting something from the django CMS content into the template.

The good: the admin. The admin has its quirks, but it works very well. One third of the CMS code is admin-related.

They have a plugin mechanism, often centered around providing placeholders that can later be inserted into the page. A plugin looks very much like a view and is often used in the same way: it has to render content for the web page. There’s also a mechanism that works much the same as middleware and context processors in django itself would.

It is all very database-intensive, so django CMS tries to cache things a lot.

The bad: the ORM. Actually, the bad is the way django CMS uses the ORM. The ORM itself is badass :-) CMS pages and plugins are structured in tree structures (via mptt or treebeard). This also translates into a heavily-customized admin changelist that renders as a tree.

Django CMS keeps a draft and a live version of each page. For each language. And titles are separate models. Also with draft/live. When going live with a page, various items need to be copied over draft to live and from a draft hiearchy into a live one. It are all database objects that have to point at each other where necessary. In this process they even sometimes set primary keys, which looked moderately scary. Quite scary, actually. It works though! And it has worked for many years.

The django ORM is very flexible and allows many tricks.

The ugly: the urlconf. There is no clean way to cleanly extend and customize the url resolver. Django needs it as it wants to integrate existing applications inside the url space of the CMS page tree.

They use apphooks to do this. You add an “apphook” plugin to a page and thereby “mount” an existing django app under the page’s url. This needs some serious urlconf trickery. It works by explcitly getting the available apphooks and to extract urls from them and then to explicitly extend the urlpatterns in your urls.py.

Problem: the urlconf is read only once at django startup. And every time you add an apphook plugin, you’d have to restart django to get the extra urls in your urlconf! There is a partial solution for that now in the form of aldryn-apphooks-config which works on the basis of url namespaces.

An even better fix is the urlconf reload improvement done in version 3.2. It uses a middleware that means one extra DB hit per request. If a change to the urlhooks is detected, all the urlconf related modules are purged from sys.modules

Signal at Sourbrodt, Belgium

Image: cycling on old railways, in this case the former ‘Vennbahn’ near Sourbrodt, Belgium.

water-gerelateerd Python en Django in het hartje van Utrecht!
 
vanrees.org logo

Reinout van Rees

My name is Reinout van Rees and I program in Python, I live in the Netherlands, I cycle recumbent bikes and I have a model railway.

Weblog feeds

Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):