.. _upgrade-to-5.1.0: ################### 5.1.0a1 release notes ################### *February 14, 2026* Welcome to django CMS 5.1.0a1! These release notes cover the new features, as well as some backwards incompatible changes you'll want to be aware of when upgrading from django CMS 4.0 or earlier. We've begun the deprecation process for some features. See the How to upgrade to 5.1.0a1 to a newer version guide if you’re updating an existing project. ******************************* Django and Python compatibility ******************************* django CMS supports **Django 4.2, 5.0, 5.1, and 5.2**. We highly recommend and only support the latest release of each series. It supports **Python 3.11, 3.12, 3.13, and 3.14**. As for Django we highly recommend and only support the latest release of each series. *********************** How to upgrade to 5.1.0 *********************** ******************* What's new in 5.1.0 ******************* New UI design ============= The most prominent change in django CMS 5.1.0 is the new user interface design. While functionally similar to the previous design, it offers a more modern and streamlined experience, better color contrast, and more consistency between the frontend editor and Django's admin interface. Key changes include: * More Django-like green based color prefers-color-scheme * Modern design with round corners and updated icons * Improved visual hierarchy and spacing It is active by default, but the legacy design can be re-enabled by adding the ``data-cms-theme`` attribute with the value ``4`` to the ```` tag in your templates. More flexible site configurations ================================= The Django admin app does not have to be available on all sites. You can now configure which sites have access to the admin interface and still edit all sites using the admin's frontend editing and preview endpoints. This is especially useful if you do not want to expose the admin interface on external production sites. You can now run multiple sites with one settings file. If you omit the ``SITE_ID`` in your settings, django CMS will determine the current site using Django's site framework based on the request's host header. This allows you to run multiple sites with one instance and one settings file. Note, that apphooks must not share the same URLs in such a scenario to avoid conflicts. If you need more complex site determination logic, you can implement a custom middleware that sets ``request.site`` accordingly. It will be respected by django CMS. For a step‑by‑step guide and examples, see :doc:`../how_to/03-multi-site` (including notes on apphook isolation and URL conflicts). For management commands that run without an HTTP request, consult :doc:`../reference/cli` for options like ``--site`` to select the target site context. Model-specific plugins ====================== Plugins can now be restricted to specific models using two complementary filters: - Plugin-level: ``CMSPluginBase.allowed_models`` — list of model identifiers (``"app_label.modelname"``) with the two special values ``None`` (allowed everywhere) and ``[]`` (allowed nowhere). - Model-level: ``Model.allowed_plugins`` — list of plugin class names, with the special value ``None`` (all plugins allowed, subject to their own ``allowed_models``). Both filters must pass for the frontend editor offer plugins to the users. This is particularly useful for plugins that are bound to specific Django models and should not be available to editors on other models - or to restrict certain models to a curated set of plugins. Example:: class TextFieldPlugin(CMSPluginBase): render_template = "forms/fields/text.html" allowed_models = ["my_form_app.form"] class Form(models.Model): fields = PlaceholderRelationField("fields") allowed_plugins = ["TextFieldPlugin"] See also the how-to guide for details and more examples: :ref:`plugin-model-restrictions`. Minor features ============== * Async support: User middleware and apphook registration support async setups and now let you run django CMS using asgi. Database access is avoided when registering apphook URLs to make them async-safe. * Apphooks now by default allow access to the page content object's placeholders on the apphook's root page. * Allow page permission change from advanced settings with appropriate permissions * Add icon for redirected pages in page tree * Let the "eye" icon in the page tree directly go to edit endpoints for editable content * Preserve GET parameters when switching to preview or edit mode * Improved UX for external placeholders (e.g., static aliases) * Optimized placeholder and plugin utilities for better performance * Re-introduced help menu * Django 6 compatibility support * Introduce contracts for django CMS Extensions Bug Fixes ========= * Get_permissions failed for missing global permissions * Create page wizard not available on empty install * Make Placeholder.add_plugin() set plugin.instance to self * Resolve empty page_title in frontend edit mode for apphooks * Improve anti-aliasing of django CMS logo png * Use PageContent.template_choices attribute for template choices instead of settings * Existing child plugin restriction cannot be reduced to an empty list (which implies all plugins allowed) * Gracefully handle unresolvable extends variables in placeholder scanning * Allow frontend-editable models to omit get_template method * Safe fallback for includes when scanning for placeholders * Fix ApphookReloadMiddleware not handling new language variants * Copying failed if a target placeholders was missing * Grouper admin kept read-only fields as prepopulated fields ************************************** Backward incompatible changes in 5.1.0 ************************************** Features deprecated in 5.1.0 ============================ Page model ---------- * The manager method ``Page.objects.get_title(page, language, language_fallback=False)`` will be removed in django CMS 6.0. Use ``page.get_content_obj()`` or ``page.get_admin_content()`` instead. * ``Page`` attribute ``page.parent_page`` is deprecated. Instead use the attribute ``page.parent``. * ``Page`` method ``page.get_parent_page()`` is deprecated and will be removed in django CMS 6.0. Instead use the `page.parent` attribute. * ``Page`` attribute ``page.languages`` is deprecated and will be removed in django CMS 6.0. Use ``page.get_languages()`` instead. * ``Page`` methods ``page.remove_language()`` and ``page.update_languages()`` are deprecated and will be removed in django CMS 6.0. They have no effect any more. * ``Page`` method ``page.get_published_languages()`` is deprecated and will be removed in django CMS 6.0. Use ``page.get_languages(admin_manager=False)`` instead. * ``Page`` method ``page.set_translations_cache()`` is deprecated and will be removed in django CMS 6.0. Use ``page.get_content_obj()`` instead - it leaves the translations cache populated. For admin views use ``page.set_admin_content_cache()`` instead. * ``Page`` methods ``page.copy()`` and ``page.copy_descendant()``have a keyword argument ``parent_node`` which has been renamed to ``parent_page``. ``parent_node`` is deprecated and will be removed in django CMS 6.0. Page permissions ---------------- * ``PagePermission``method ``permission.get_page_ids()`` is deprecated and will be removed in django CMS 6.0. Use ``permission.get_page_permission_tuple()`` instead for faster permission checks by path and not id. Plugin rendering ---------------- * ``BaseRenderer`` method ``renderer.get_placeholder_toolbar_js()`` has a keyword argument ``page`` which will be removed in django CMS 6.0. It can already be safely removed from all calls. Utility functions ----------------- * Most ``cms.utils.i18n`` utility functions accepting an optional ``site_id`` argument will require this argument in django CMS 6.0. These functions are ``get_languages()``, ``get_language_code()``, ``get_language_list()``, ``get_language_tuple()``, ``get_language_dict()``, ``get_public_languages()``, ``get_language_object()``, ``get_language_objects()``, ``get_default_language()``, ``get_fallback_languages()``, ``get_redirect_on_fallback()``, and ``hide_untranslated()``. * ``cms.utils.page_permissions.user_can_add_page()`` and ``cms.utils.page_permissions.has_generic_permission`` accepting an optional ``site`` argument will require this argument in django CMS 6.0. * ``cms.utils.page.get_page_queryset()`` is deprecated and will be removed in django CMS 6.0. Use ``Page.objects.on_site(site)`` instead. * ``cms.utils.placeholder.get_toolbar_plugin_struct()`` has a keyword argument ``page`` which has been renamed to ``obj``. ``page`` is deprecated and will be removed in django CMS 6.0. Wizard helpers -------------- * The ``cms.wizards.helpers`` module has been deprecated and will be removed in django CMS 6.0. Use ``cms.wizards.wizard_base.get_entries()`` and ``cms.wizards.wizard_pool.get_entry()`` instead. Removal of deprecated functionality =================================== API --- ``cms.api.create_title`` has been removed. Use :meth:`cms.api.create_page_content` instead. ``StaticPlaceholder`` --------------------- * ``StaticPlaceholder`` has been removed from ``cms.models`` and ``cms.admin``. Use `static aliases `_ instead. * This implies that ``cms.plugin_rendering`` does not accept static placeholders any more. * The ``static_placeholder`` template tag has been removed. Placeholders ------------ * ``PlaceholderField`` has been removed from ``cms.fields``. Use :class:`~cms.models.fields.PlaceholderRelationField` in conjunction with :meth:`~cms.utils.placeholder.get_placeholder_from_slot` instead (also see :ref:`placeholders_outside_cms`). * ``PlaceholderAdminMixin`` has been removed from ``cms.admin``. It is not needed anymore and can be safely removed from your code. * A placeholder's ``actions`` property (deprecated in django CMS 5) has been removed. This also includes the removal of the two classes ``cms.utils.placeholder.PlaceholderNoAction`` and ``cms.utils.placeholder.MLNGPlaceholderActions``. If you need these classes, move them to your own codebase. Permissions ----------- ``cms.utils.permissions.has_page_permission()`` has been removed. Use :func:`cms.utils.page_permissions.has_generic_permission()` instead. As part of performance improvements, the following methods have been removed from ``cms.utils.page_permissions``. They were deprecated in django CMS 4.1: * ``cms.utils.page_permissions.get_add_ids()`` * ``cms.utils.page_permissions.get_change_ids()`` * ``cms.utils.page_permissions.get_change_advanced_settings_ids()`` * ``cms.utils.page_permissions.get_change_permissions_ids()`` * ``cms.utils.page_permissions.get_get_delete_ids()`` * ``cms.utils.page_permissions.get_move_page_ids()`` * ``cms.utils.page_permissions.get_publish_ids()`` * ``cms.utils.page_permissions.get_view_ids()`` * ``cms.utils.permissions.get_view_restrictions()`` Menus ----- * ``cms.cms_menus.get_visible_nodes`` has been removed. Use ``cms.cms_menus.get_visible_page_contents`` instead. * ``cms.cms_menus.get_menu_node_for_page`` has been removed. Use ``cms.cms_menus.get_menu_node_for_page_content`` instead. Miscellaneous ------------- * The ``title`` property has been removed from ``cms.cms_toolbars.PageToolbar``. Use ``cms.cms_toolbars.PageTooolbar.page_content`` instead. * ``cms.forms.get_root_nodes`` has been removed. Use ``cms.cms_menus.get_root_pages`` instead. * ``cms.extensions.toolbar.ExtensionToolbar.get_title_extension_admin`` has been removed. Use ``cms.extensions.toolbar.ExtensionToolbar.get_page_content_extension_admin`` instead. * ``cms.toolbar.utils.get_plugin_tree_as_json`` has been removed. Use ``cms.toolbar.utils.get_plugin_tree`` and convert the result to JSON instead.