Content: Blog


Announcing support for Django 1.9

Martin Koistinen

March 3, 2016


We are happy to announce Django 1.9 compatibility* as of django CMS 3.2.2.

This makes django CMS 3.2.2 the most Django-compatible version of the CMS ever with support for Django 1.6, 1.7, 1.8 (LTS) and now 1.9. This release provides the ideal version to upgrade to, in preparation for the upcoming 3.3 release which will drop support for Django 1.6 and 1.7.


Other features:

  • Substantial "under-the-hood" improvements to the page tree resulting in significant reduction of page-tree reloads and generally cleaner code
  • Update jsTree version to 3.2.1 with slight adaptions to the Pagetree
  • Improve the display and useability of the language menu, especially in cases where there are many languages
  • Documentation improvements
  • Add support for django-reversion 1.10+ (required for Django 1.9).
  • Add placeholder name to the edit tooltip.
  • Add attr['is_page']=True to CMS Page navigation nodes.
  • Add Django and Python versions to debug bar info tooltip.


And fixes:

  • Fix an issue relating to search fields in plugins
  • Fix an issue where the app-resolver would trigger locales into migrations
  • Fix cache settings
  • Fix ToolbarMiddleware.is_cms_request logic
  • Fix numerous Django 1.9 deprecations
  • Numerous other improvements to overall stability and code quality
  • Fix an issue with refreshing the UI when switching CMS language
  • Fix an issue with sideframe urls not being remembered after reload
  • Fix breadcrumb in page revision list
  • Fix clash with Foundation that caused "Add plugin" button to be unusable
  • Fix a tree corruption when pasting a nested plugin under another plugin
  • Fix message with CMS version not showing up on hover in debug mode
  • Fix messages not being positioned correctly in debug mode
  • Fix an issue where plugin parent restrictions where not respected when pasting a plugin
  • Fix an issue where "Copy all" menu item could've been clicked on empty placeholder
  • Fix a bug where page tree styles didn't load from STATIC_URL that pointed to a different host
  • Fix an issue where the side-frame wouldn't refresh under some circumstances
  • Honor CMS_RAW_ID_USERS in GlobalPagePermissionAdmin
  • Fix for failing to work in some circumstances

Note that the above features and fixes includes the same from the unannounced release of django CMS 3.2.1.


Version 3.1.5

Version 3.1.5 has also been released with a number of the above-mentioned fixes. Please see its release notes here.



Many thanks to all community members who have submitted issue reports and especially to these GitHub users who have also submitted pull requests: Tim Graham, Steffen Jasper, Dave Hall, Stephen Paulger, Tadas Dailyda and others.


*Important Issues Arise When Using Django 1.9

Django 1.9 is lot stricter about collisions in the `related_names` of relationship fields than previous versions of Django. This has brought to light issues in django CMS relating to the private field `CMSPlugin.cmsplugin_ptr`. The issue becomes apparent when multiple packages are installed that provide plugins with the same model class name. A good example would be if you have the package `djangocms-file` installed, which has a poorly named CMSPlugin model subclass called `File`, then any other package that has a plugin with a field named "file" would most likely cause an issue. Considering that `djangocms-file` is a very common plugin to use and a field name of "file" is not uncommon in other plugins, this is less than ideal.

Fortunately, developers can correct these issues in their own projects while they await improvements in django CMS. There is an internal field that is created when instantiating plugins: `CMSPlugin.cmsplugin_ptr`. This private field is declared in the CMSPlugin base class and is populated on instantiation using the lower-cased model name of the CMSPlugin subclass that is being registered.

A subclass to CMSPlugin can declare their own cmsplugin_ptr field to immediately fix this issue. The easiest solution is to declare this field with a `related_name` of "+". In typical Django fashion, this will suppress the back-reference and prevent any collisions. However, if the back-reference is required for some reason (very rare), then we recommend using the pattern `%(app_label)s_%(class_name)s`. In fact, in version 3.3 of django CMS, this is precisely the string-template that the reference setup will use to create the name. Here's an example:

class MyPlugin(CMSPlugin):
    class Meta:
        app_label = 'my_package'

    cmsplugin_ptr = models.OneToOneField(

    # other fields, etc.

Please note that CMSPlugin.cmsplugin_ptr will remain a private field.


Notice of Upcoming Change in 3.3

As outlined in the section immediately above, the pattern currently used to derive a `related_name` for the private field `CMSPlugin.cmsplugin_ptr` may result in frequent collisions. In django CMS 3.3, this string-template will be changed to utilise both the `app_label` and the model class name. In the majority of cases, this will not affect developers or users, but if your project uses these back-references for some reason, please be aware of this change and plan accordingly.


blog comments powered by Disqus

Want to post your article here?

Contact us