Reference

API reference automatically generated from source code.

CMSConfig options

Declare a CMSConfig inner class on a content model to opt into CMS integration. All options are read at app startup and default to off.

Option

Default

Effect

enable_versioning

False

Register the content model with djangocms-versioning (which must be installed). If the model has a language field, language is added as an extra grouping field, giving per-language version history.

enable_frontend_editing

False

Make the content frontend-editable (double-click editing via the CMS toolbar). The grouper admin should mix in FrontendEditableAdminMixin.

apphook

False

Register a CMS app hook exposing a detail view. The URL uses the model’s slug field if present, otherwise its pk; a get_absolute_url() is injected onto the model. See Expose content at a URL (app hooks).

Whether a content model participates as a grouper/content pair is inferred from its foreign key to an AbstractCustomGrouper; a content model without such a foreign key is treated as a plain model (no versioning, apphook or grouper admin).

Related setting:

  • CMS_SETTINGS_SHORTCUT (default True) — show the settings-cog button for the current grouper in the toolbar.

Models

class djangocms_custom_content.models.AbstractCustomGrouper(*args, **kwargs)

Bases: CustomGrouperMixin, Model

Abstract base model for grouper objects.

A grouper is a container that organizes multiple language versions of content. Inherit from this model when you want to group content versions together.

The grouper automatically discovers its related content model and provides methods to access content by language.

Example:

class Article(AbstractCustomGrouper):
    '''Groups all language versions of an article.'''
    pass

class ArticleContent(AbstractCustomContent):
    article = ForeignKey(Article, on_delete=CASCADE)
    title = CharField(max_length=200)
    language = CharField(max_length=5)
Attributes:

_content_set: Cache for the related content model manager _has_language_field: Whether the content model has a language field _content_cache: Cache for retrieved content instances _is_admin_cache: Flag for admin-specific caching

get_content(language=None)

Retrieve content for this grouper in a specific language.

Uses the current language by default if no language is specified. Implements caching for performance.

Args:

language: The language code to retrieve. Defaults to current language.

Returns:

The content model instance for the specified language, or None if not found

Example:

article = Article.objects.first()
english_content = article.get_content(language='en')
german_content = article.get_content(language='de')
Parameters:

language (str | None)

Return type:

Model | None

get_admin_content(language=None)

Retrieve content for admin interface with prefetch optimization.

This method is optimized for admin display and uses prefetched data when available. It retrieves the latest published content.

Args:

language: The language code to retrieve. Defaults to current language.

Returns:

The latest content model instance for the specified language, or None if not found

Notes:

This method is primarily used by the Django admin interface.

Parameters:

language (str | None)

Return type:

Model | None

class djangocms_custom_content.models.AbstractCustomContent(*args, **kwargs)

Bases: CustomContentMixin, Model

Abstract base model providing a PlaceholderRelationField for custom content.

Inherit from this model in your project to quickly add placeholder support to your custom content types.

To relate content groupers to one another, declare a RelationField on the grouper model. See djangocms_custom_content.relations.

objects
admin_manager
placeholders

Accessor to the related objects manager on the one-to-many relation created by GenericRelation.

In the example:

class Post(Model):
    comments = GenericRelation(Comment)

post.comments is a ReverseGenericManyToOneDescriptor instance.

template_name_suffix = '_detail'
get_template()
Return type:

str

class djangocms_custom_content.models.CustomGrouperMixin

Bases: object

Mixin providing base grouper functionality.

This mixin is inherited by AbstractCustomGrouper to provide grouper model functionality. It serves as a marker class for identifying grouper models in the framework.

class djangocms_custom_content.models.CustomContentMixin

Bases: object

Mixin providing base content model functionality.

This mixin is inherited by AbstractCustomContent to provide content model functionality. It serves as a marker class for identifying content models in the framework.

Relations

class djangocms_custom_content.relations.RelationField(target, *, related_name=None, ordered=False, through_name=None)

Bases: object

Declarative grouper-to-grouper relation, à la ManyToManyField.

target may be a model class or an "app_label.Model" string naming either a grouper or its content model (resolved to the grouper). The forward accessor is installed immediately; the reverse accessor named by related_name is installed on the target once the app registry is ready.

contribute_to_class(cls, name)
class djangocms_custom_content.relations.RelationManager(instance, through, target_model, *, ordered)

Bases: object

Forward accessor owner.<field> → a queryset of target groupers.

through rows are filtered by source=owner; the target groupers are returned as a genuine queryset so all queryset methods are available. When the through is ordered, results are ordered by the through’s order.

Parameters:
  • instance (models.Model)

  • through (type[models.Model])

  • target_model (type[models.Model])

  • ordered (bool)

get_queryset()
all()
filter(*args, **kwargs)
count()
exists()
add(*objs)
remove(*objs)
set(objs)
clear()
reorder(objs)

Set explicit ordering from an iterable of grouper/content objects.

class djangocms_custom_content.relations.ReverseRelationManager(instance, through, source_model)

Bases: object

Reverse accessor target.<related_name> → queryset of source groupers.

Parameters:
  • instance (models.Model)

  • through (type[models.Model])

  • source_model (type[models.Model])

get_queryset()
all()
filter(*args, **kwargs)
count()
exists()
add(*objs)
remove(*objs)
clear()
djangocms_custom_content.relations.relation_through_factory(owner_model, *, ordered=False, name=None, module=None)

Build a concrete through model linking owner_model to any grouper.

The returned model has a concrete source FK to owner_model, the inherited generic target, a uniqueness constraint preventing duplicate edges and an index on the generic columns for fast reverse lookups.

Parameters:
  • owner_model (type[Model])

  • ordered (bool)

  • name (str | None)

  • module (str | None)

Return type:

type[Model]

djangocms_custom_content.relations.grouper_model_of(model)

Return the grouper model for a content model, else model unchanged.

Relations always target the grouper so they survive version copies. A declaration may name either the grouper or its content model; both resolve here to the grouper (“if there is one”).

Parameters:

model (type[Model])

Return type:

type[Model]

CMS Toolbars

class djangocms_custom_content.cms_toolbars.CustomContentToolbar(request, toolbar, is_current_app, app_path)

Bases: CMSToolbar

Toolbar for djangocms-custom-content.

Adds a settings icon button to the right toolbar.

classmethod get_insert_position(admin_menu, item_name)

Ensures that there is a SHORTCUTS_BREAK and returns a position for an alphabetical position against all custom content items between SHORTCUTS_BREAK, and the ADMINISTRATION_BREAK.

Args:

admin_menu: The CMS admin menu instance to inspect and modify. item_name: The menu item name used for alphabetical ordering.

Returns:

The integer position where the item should be inserted.

Add shortcut links for each configured grouper model.

add_content_object_menu()

Add menu entries for the current grouper instance.

populate()

Populate the toolbar with custom content entries.

property media

Admin

class djangocms_custom_content.admin.CustomGrouperAdminMixin

Bases: RelationAdminMixin

Admin mixin to redirect content endpoints for grouper admins.

Provides a breadcrumb redirect compatible with django CMS versioning, and (via RelationAdminMixin) renders any RelationField on the model as an autocomplete multi-select — sortable when the relation is ordered.

Prefetching of the latest related content (_admin_prefetch_cache) is handled by cms.admin.utils.GrouperModelAdmin.get_queryset, which the concrete admin classes inherit from, so this mixin does not override get_queryset.

get_urls()

Register breadcrumb redirect URLs for grouper admin views.

breadcrumb_redir(request, *args, **kwargs)

Redirect versioning breadcrumb URLs to the grouper admin.

djangocms-versioning uses content admin URLs for breadcrumbs, but this project uses grouper admin classes and must redirect accordingly.

class djangocms_custom_content.relation_admin.RelationAdminMixin

Bases: object

Renders the model’s relation fields (declared by RelationModelForm) with autocomplete widgets — sortable when the relation is ordered.

Field creation, initial values and saving live in RelationModelForm; this mixin only ensures that form is in use, swaps in the autocomplete widgets, and serves the autocomplete endpoint. Set relation_autocomplete = False to opt out.

relation_autocomplete = True
get_urls()
relation_autocomplete_view(request)
get_form(request, obj=None, **kwargs)

Helpers

djangocms_custom_content.helpers.get_custom_config(model)

Return the custom content configuration tuple for the given model.

Looks up the model in the custom_content_groupers registry and returns a tuple of (content_model, grouper_field_name, enable_versioning). If the model is not registered, returns (None, None, False).