Extensible models

In AlekSIS you can use ExtensibleModels to add model fields to other apps models.

If you want to make your apps models extensible, use the ExtensibleModel class as parent class of your models.

class aleksis.core.mixins.AdvancedCreateView(**kwargs)[source]
class aleksis.core.mixins.AdvancedDeleteView(**kwargs)[source]

Common confirm view for deleting.


Using this view, objects are deleted permanently after confirming. We recommend to include the mixin reversion.views.RevisionMixin from django-reversion to enable soft-delete.

delete(request, *args, **kwargs)[source]

Call the delete() method on the fetched object and then redirect to the success URL.

class aleksis.core.mixins.AdvancedEditView(**kwargs)[source]
class aleksis.core.mixins.BaseModelAdmin(model, admin_site)[source]

A base class for ModelAdmin combining django-guardian and rules.

class aleksis.core.mixins.ExtensibleForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None, use_required_attribute=None, renderer=None)[source]

Base model for extensible forms.

This mixin adds functionality which allows - apps to add layout nodes to the layout used by django-material

Add layout nodes

from material import Fieldset

from aleksis.core.forms import ExampleForm

node = Fieldset("field_name")
classmethod add_node_to_layout(node)[source]

Add a node to layout attribute.


node (LayoutNode) – django-material layout node (Fieldset, Row etc.)

class aleksis.core.mixins.ExtensibleModel(*args, **kwargs)[source]

Base model for all objects in AlekSIS apps.

This base model ensures all objects in AlekSIS apps fulfill the following properties:

  • versions property to retrieve all versions of the model from reversion

  • Allow injection of fields and code from AlekSIS apps to extend model functionality.

After all apps have been loaded, the code in the model_extensions module in every app is executed. All code that shall be injected into a model goes there.


from datetime import date, timedelta

from jsonstore import CharField

from aleksis.core.models import Person
def is_cool(self) -> bool:
    return True
def age(self) -> timedelta:
    return self.date_of_birth -


For a more advanced example, using features from the ORM, see AlekSIS-App-Chronos and AlekSIS-App-Alsijil.



  • site (ForeignKey to Site) – Site

  • extended_data (JSONField) – Extended data

classmethod add_permission(name, verbose_name)[source]

Dynamically add a new permission to a model.

classmethod class_method(func, name=None)[source]

Add the passed callable as a classmethod.

Return type


classmethod field(**kwargs)[source]

Add the passed jsonstore field. Must be one of the fields in django-jsonstore.

Accepts exactly one keyword argument, with the name being the desired model field name and the value the field instance.

Return type


classmethod foreign_key(field_name, to, to_field='pk', to_field_type=<class 'jsonstore.fields.IntegerField'>, related_name=None)[source]

Add a virtual ForeignKey.

This works by storing the primary key (or any field passed in the to_field argument) and adding a property that queries the desired model.

If the foreign model also is an ExtensibleModel, a reverse mapping is also added under the related_name passed as argument, or this model’s default related name.

Return type



Get the URL o a view representing this model instance.

Return type


classmethod method(func, name=None)[source]

Add the passed callable as a method.

Return type


classmethod property_(func, name=None)[source]

Add the passed callable as a property.

Return type


save(*args, **kwargs)[source]

Ensure all functionality of our extensions that needs saving gets it.


Annotate a ObjectPermissionChecker for use with permission system.

classmethod syncable_fields(recursive=True, exclude_remotes=[])[source]

Collect all fields that can be synced on a model.

If recursive is True, it recurses into related models and generates virtual proxy fields to access fields in related models.

Return type


classmethod syncable_fields_choices()[source]

Collect all fields that can be synced on a model.

Return type

tuple[tuple[str, str]]

classmethod syncable_fields_choices_lazy()[source]

Collect all fields that can be synced on a model.

Return type

Callable[[], tuple[tuple[str, str]]]

property versions

Get all versions of this object from django-reversion.

Includes diffs to previous version.

Return type

list[tuple[str, tuple[Any, Any]]]

class aleksis.core.mixins.GlobalPermissionModel(*args, **kwargs)[source]

Base model for global permissions.

This base model ensures that global permissions are not managed.

class aleksis.core.mixins.PureDjangoModel[source]

No-op mixin to mark a model as deliberately not using ExtensibleModel.

class aleksis.core.mixins.SchoolTermRelatedExtensibleForm(*args, **kwargs)[source]

Extensible form for school term related data.


This doesn’t automatically include the field school_term in fields or layout, it just sets an initial value.

__init__(*args, **kwargs)[source]

Initialize self. See help(type(self)) for accurate signature.

class aleksis.core.mixins.SchoolTermRelatedExtensibleModel(*args, **kwargs)[source]

Add relation to school term.

  • site (ForeignKey to Site) – Site

  • extended_data (JSONField) – Extended data

  • school_term (ForeignKey to SchoolTerm) – Linked school term

class aleksis.core.mixins.SuccessMessageMixin[source]

If the form is valid, save the associated model.

Return type