Utility functions#
Utility functions provide functionality that is regularly used within the django CMS core and are also available to third party packages.
Model admin#
Grouper admin#
- class cms.admin.utils.GrouperModelAdmin(model, admin_site)#
Bases:
ChangeListActionsMixin
,ModelAdmin
Easy-to-use ModelAdmin for grouper models. Usage example:
class MyGrouperAdmin(GrouperModelAdmin): # Add language tabs to change and add views extra_grouping_fields = ("language",) # Add grouper and content fields to change list view # Add preview and settings action to change list view list_display = ("field_in_grouper_model", "content__field_in_content_model", "admin_list_actions") # Automatically add content fields to change form (either the standard form or any form given form = MyChangeForm ...
Using
GrouperModelAdmin
instead ofModelAdmin
adds a view standard functions to your admin class to make it more easily and more consistently customizable.- By adding
"admin_list_actions"
to the admin’slist_display
attribute the change list view gets an action column as described by
ChangeListActionsMixin
.
- By adding
- The admin class automatically creates a method for each field of the content model form (default: all fields)
named
content__{content_model_field_name}
. Those fields can be used inlist_display
just as grouper model fields. Currently, they are not sortable, however.
- The change form is amended with exactly those content fields also named
content__{content_model_field_name}
. As a result, the change form can (but does not have to) contain both grouper model fields and content model fields. The admin takes care of creating the necessary model instances.
- The change form is amended with exactly those content fields also named
- changeform_view(request: HttpRequest, object_id: Optional[str] = None, form_url: str = '', extra_context: dict = None) HttpResponse #
Update grouping field properties for both add and change views
- delete_view(request: HttpRequest, object_id: str, extra_context: Optional[dict] = None) HttpResponse #
Update grouping field properties for delete view
- get_actions_list() list #
Collect list actions from implemented methods and return as list. Make sure to call it’s
super()
instance when overwriting:class MyModelAdmin(admin.ModelAdmin): ... def get_actions_list(self): return super().get_actions_list() + [self.my_first_action, self.my_second_action]
- get_changelist(request: HttpRequest, **kwargs) type #
Allow for extra grouping fields as a non-filter parameter
- get_changelist_instance(request: HttpRequest) GrouperChangeListBase #
Update grouping field properties and get changelist instance
- get_content_field(obj: Model, field_name: str, request: Optional[HttpRequest] = None) Any #
Retrieves the content of a field stored in the content model. If request is given extra grouping fields are processed before.
- get_extra_context(request: HttpRequest, object_id: Optional[str] = None) Dict[str, Any] #
Provide the grouping fields to the change view.
- get_form(request: HttpRequest, obj: Optional[Model] = None, **kwargs) type #
Adds the language from the request to the form class
- get_grouper_obj(obj: Model) Model #
Get the admin object. If obj is a content object assume that the admin object resides in the field named after the admin model. The admin model name must be the same as the content model name minus “Content” at the end.
- get_grouping_from_request(request: HttpRequest) None #
Retrieves the current grouping selectors from the request
- get_language_from_request(request: HttpRequest) str #
Hook for get_language_from_request which by default uses the cms utility
- get_language_tuple() Tuple[Tuple[str, str], ...] #
Hook on how to get all available languages for the language selector.
- get_preserved_filters(request: HttpRequest) str #
Always preserve grouping get parameters! Also, add them to changelist filters: * Save and continue will keep the grouping parameters * Save and returning to changelist will keep the grouping parameters
- get_queryset(request: HttpRequest) QuerySet #
Annotates content fields with the name “content__{field_name}” to the grouper queryset if for all content fields that appear in the
- get_readonly_fields(request: HttpRequest, obj: Optional[Model] = None)#
Allow access to content fields to be controlled by a method “can_change_content”: This allows versioned content to be protected if needed
- history_view(request: HttpRequest, object_id: str, extra_context: Optional[dict] = None) HttpResponse #
Update grouping field properties for history view
- save_model(request: HttpRequest, obj: Model, form: Form, change: bool) None #
Save/create both grouper and content object
- view_on_site(obj: Model) Optional[str] #
bool(x) -> bool
Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.
- content_model: Optional[Model] = None#
The content model class to be used. Defaults to the model class named like the grouper model class plus
"Content"
at the end from the same app as the grouper model class, e.g.,BlogPostContent
if the grouper isBlogPost
.
Name of the inverse relation field giving the set of content models belonging to a grouper model. Defaults to the first field found as an inverse relation. If you have more than one inverse relation please make sure to specify this field. An example would be if the blog post content model contained a many-to-many relationship to the grouper model for, say, related blog posts.
- property current_content_filters: Dict[str, Any]#
Filters needed to get the correct content model instance
- extra_grouping_fields: Tuple[str, ...] = ()#
Indicates additional grouping fields such as
"language"
for example. Additional grouping fields create tabs in the change form and a dropdown menu in the change list view.Note
All fields serving as extra grouping fields must be part of the admin’s
fieldsets
setting forGrouperModelAdmin
to work properly. In the change form the fields will be invisible.
Placeholders#
- cms.utils.placeholder.get_placeholder_from_slot(placeholder_relation: Manager, slot: str, template_obj=None) Placeholder #
Retrieves the placeholder instance for a PlaceholderRelationField either by scanning the template of the template_obj (if given) or by creating or getting a Placeholder in the database
- cms.utils.placeholder.get_declared_placeholders_for_obj(obj: Optional[Model]) list[cms.models.placeholdermodel.Placeholder] #
Returns declared placeholders for an object. The object is supposed to have a method
get_template
which returns the template path as a string that renders the object.get_declared_placeholders
returns a list of placeholders used in the template by the{% placeholder %}
template tag.
Plugins#
- cms.utils.plugins.get_plugins(request, placeholder, template, lang=None)#
Get a list of plugins for a placeholder in a specified template. Respects the placeholder’s cache.
- Parameters:
request – (HttpRequest) The HTTP request object.
placeholder – (Placeholder) The placeholder object for which to retrieve plugins.
template – (Template) The template object in which the placeholder resides (not used).
lang – (str, optional) The language code for localization. Defaults to None.
- Returns:
list: A list of plugins for the specified placeholder in the template.
- Raises:
None.
Examples:
# Get plugins for a placeholder in a template plugins = get_plugins(request, placeholder, template) # Get plugins for a placeholder in a template with specific language plugins = get_plugins(request, placeholder, template, lang='en')
- cms.utils.plugins.assign_plugins(request, placeholders, template=None, lang=None)#
Fetch all plugins for the given
placeholders
and cast them down to the concrete instances in one query per type.- Parameters:
request – The current request.
placeholders – An iterable of placeholder objects.
template – (optional) The template object.
lang – (optional) The language code.
This method assigns plugins to the given placeholders. It retrieves the plugins from the database based on the placeholders and the language. The plugins are then downcasted to their specific plugin types.
The plugins are split up by placeholder and stored in a dictionary where the key is the placeholder ID and the value is a list of plugins.
For each placeholder, if there are plugins assigned to it, the plugins are organized as a layered tree structure. Otherwise, an empty list is assigned.
The list of all plugins for each placeholder is stored in the _all_plugins_cache attribute of the placeholder, while the list of root plugins is stored in the _plugins_cache attribute
- cms.utils.plugins.has_reached_plugin_limit(placeholder, plugin_type, language, template=None)#
Checks if the global maximum limit for plugins in a placeholder has been reached. If not then it checks if it has reached its maximum plugin_type limit.
Parameters: - placeholder: The placeholder object to check the limit for. - plugin_type: The type of plugin to check the limit for. - language: The language code for the plugins. - template: The template object for the placeholder. Optional.
Returns: - False if the limit has not been reached.
Raises: - PluginLimitReached: If the limit has been reached for the placeholder.
- cms.utils.plugins.get_plugin_class(plugin_type: str) CMSPluginBase #
Returns the plugin class for a given plugin_type (str)
- cms.utils.plugins.get_plugin_model(plugin_type: str) CMSPlugin #
Returns the plugin model class for a given plugin_type (str)
- cms.utils.plugins.get_plugins_as_layered_tree(plugins)#
Given an iterable of plugins ordered by position, returns a deque of root plugins with their respective children set in the child_plugin_instances attribute.
- cms.utils.plugins.copy_plugins_to_placeholder(plugins, placeholder, language=None, root_plugin=None, start_positions=None)#
Copies an iterable of plugins to a placeholder
- Parameters:
plugins (iterable) – Plugins to be copied
placeholder (
cms.models.pluginmodel.CMSPlugin
instance) – Target placeholderlanguage (str) – target language (if no root plugin is given)
root_plugin –
start_positions (int) – Cache for start positions by language
The logic of this method is the following:
Get bound plugins for each source plugin
Get the parent plugin (if it exists)
then get a copy of the source plugin instance
Set the id/pk to None to it the id of the generic plugin instance above; this will effectively change the generic plugin created above into a concrete one
find the position in the new placeholder
save the concrete plugin (which creates a new plugin in the database)
trigger the copy relations
return the plugin ids
- cms.utils.plugins.downcast_plugins(plugins, placeholders=None, select_placeholder=False, request=None)#
Downcasts the given list of plugins to their respective classes. Ignores any plugins that are not available.
- Parameters:
plugins (List[CMSPlugin]) – List of plugins to downcast.
placeholders (Optional[List[Placeholder]]) – List of placeholders associated with the plugins.
select_placeholder (bool) – If True, select_related the plugin queryset with placeholder.
request (Optional[HttpRequest]) – The current request.
- Returns:
Generator that yields the downcasted plugins.
- Return type:
Generator[CMSPlugin, None, None]
- cms.utils.plugins.get_bound_plugins(plugins)#
Get the bound plugins by downcasting the plugins to their respective classes. Raises a KeyError if the plugin type is not available.
Creates a map of plugin types and their corresponding plugin IDs for later use in downcasting. Then, retrieves the plugin instances from the plugin model using the mapped plugin IDs. Finally, iterates over the plugins and yields the downcasted versions if they have a valid parent. Does not affect caching.
- Parameters:
plugins (List[CMSPlugin]) – List of
CMSPlugin
instances.- Returns:
Generator that yields the downcasted plugins.
- Return type:
Generator[CMSPlugin, None, None]
Example:
plugins = [plugin_instance1, plugin_instance2] for bound_plugin in get_bound_plugins(plugins): # Do something with the bound_plugin pass