Model Mixins and QuerySets

Mixins

Loggable

New in version 0.7.

class djem.models.Loggable(*args, **kwargs)[source]

A mixin for creating, storing, and retrieving logs on an instance. Named logs are stored internally on the Loggable instance and persist for the lifetime of the object. A single log is “active” at any given time and can be freely appended to while it is.

Adds instance-based logging support to any model.

start_log(name)[source]

Start a new log with the given name. The new log becomes the current “active” log. Queue any previous active log so that it can be reactivated when the new log is either finished or discarded.

Parameters

name – The name of the log.

end_log()[source]

End the currently active log and return a (name, log) tuple, where name is the name of the log that was ended and log is a list of the entries that have been added to the log. Reactivate the previous log, if any.

The returned list will be a copy of the one used to store the log internally, allowing it to be safely manipulated without affecting the original log.

A log must be ended in order to be retrieved.

Returns

A (name, log) tuple.

discard_log()[source]

Discard the currently active log. Reactivate the previous log, if any.

log(*lines, tag=None)[source]

Append to the currently active log. Each given argument will be added as a separate line to the log. If tag is specified, each added line will be tagged with the given value.

Parameters
  • lines – Individual lines to add to the log.

  • tag – A tag to apply to each line.

get_log(name, tags=None, raw=False)[source]

Return the named log, as a string. The log must have been ended (via end_log()) in order to retrieve it.

Return a raw list of lines in the log if raw=True. In this case, the returned list will be a copy of the one used to store the log internally, allowing it to be safely manipulated without affecting the original log.

Whether returning a string or a list, use tags to filter the included lines to just those with at least one of the given tags.

Parameters
  • name – The name of the log to retrieve.

  • tags – An iterable of tags to filter the log by.

  • rawTrue to return the log as a list. Returned as a string by default.

Returns

The log, either as a string or a list.

get_last_log(tags=None, raw=False)[source]

Return the most recently finished log, as a string.

Return a raw list of lines in the log if raw=True. In this case, the returned list will be a copy of the one used to store the log internally, allowing it to be safely manipulated without affecting the original log.

Whether returning a string or a list, use tags to filter the included lines to just those with at least one of the given tags.

Parameters
  • tags – An iterable of tags to filter the log by.

  • rawTrue to return the log as a list. Returned as a string by default.

Returns

The log, either as a string or a list.

OLPMixin

New in version 0.7.

class djem.models.OLPMixin(*args, **kwargs)[source]

A companion to Django’s PermissionsMixin that enables additional advanced features of the object-level permission system. It is not necessary to use this mixin in order to use object-level permissions, it just provides additional functionality (such as logging permission checks, optionally allowing superusers to be restricted by object-level conditions, etc).

Inherits instance-based logging functionality from Loggable. For more information on the available features, see Advanced Features.

has_perm(perm, obj=None)[source]

A replacement for the default has_perm() method defined by Django’s PermissionsMixin.

In conjunction with the DJEM_UNIVERSAL_OLP setting, this version can force superusers to be subject to the same object-level permissions checks as regular users.

In conjunction with the DJEM_PERM_LOG_VERBOSITY, an automatic log of all permission checks can be kept, using instance-based logging.

clear_perm_cache()[source]

Clear the object-level and model-level permissions caches on the user instance.

Auditable

Changed in version 0.7: Renamed from CommonInfoMixin. The old name is still available for backwards compatibility, but is considered deprecated.

class djem.models.Auditable[source]

Auditable is a model mixin class that provides:

save(user=None, *args, **kwargs)[source]

Overridden to ensure the user_modified and date_modified fields are always updated. The user argument is required and must be passed a User instance, unless the DJEM_AUDITABLE_REQUIRE_USER_ON_SAVE setting is False.

owned_by(user)[source]

Return True if user_created matches the given user, otherwise return False. The user can be given as an id or a User instance.

See also

AuditableQuerySet

The custom QuerySet used by Auditable.

AuditableForm

A ModelForm subclass that supports Auditable models.

UserSavable

A ModelForm mixin to add support for Auditable models, for forms that already have a known user.

Archivable

Changed in version 0.7: Renamed from ArchivableMixin. The old name is still available for backwards compatibility, but is considered deprecated.

class djem.models.Archivable[source]

Archivable is a model mixin class that provides:

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

Archive this record.

Accepts all arguments of the save method, as it saves the instance after setting the is_archived flag. It saves using the update_fields keyword argument, containing the is_archived field, whether it was provided to this method or not. If provided, it is extended, not replaced.

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

Unarchive this record.

Accepts all arguments of the save method, as it saves the instance after setting the is_archived flag. It saves using the update_fields keyword argument, containing the is_archived field, whether it was provided to this method or not. If provided, it is extended, not replaced.

See also

ArchivableQuerySet

The custom QuerySet used by Archivable.

Versionable

Changed in version 0.7: Renamed from VersioningMixin. The old name is still available for backwards compatibility, but is considered deprecated.

class djem.models.Versionable[source]

Versionable is a model mixin class that provides:

  • A version field that is automatically incremented on every save.

  • An overridden objects Manager that provides access to the custom VersionableQuerySet.

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

Overridden to ensure the version field is always updated.

exception AmbiguousVersionError[source]

A subclass of ModelAmbiguousVersionError specific to the Versionable class. Raised when attempting to access the version field after it has been atomically incremented.

See also

VersionableQuerySet

The custom QuerySet used by Versionable.

QuerySets

MixableQuerySet

New in version 0.7.

class djem.models.MixableQuerySet[source]

A mixin for QuerySet classes that simply provides an enhanced as_manager() method that can be used to combine the queryset class with any number of other queryset classes automatically.

classmethod as_manager(*other_querysets)[source]

Similar to the as_manager classmethod available on regular Django queryset classes, this returns an instance of Manager with a copy of the queryset’s methods. However, it also accepts other queryset classes as arguments and includes their methods in the created Manager also. This allows easily creating combinations of this queryset class with other custom queryset classes, without needing to manually create an extra class to do the grouping.

This is only useful where the querysets being combined do not contain conflicting methods. Method inheritance is supported (i.e. multiple querysets can contain the same method and they will be resolved in normal method resolution order), but depending on the logic of those methods, they may not be compatible. In such cases, an extra class resolving any incompatibilities is still required.

AuditableQuerySet

Changed in version 0.7: Renamed from CommonInfoQuerySet. The old name is still available for backwards compatibility, but is considered deprecated.

class djem.models.AuditableQuerySet(model=None, query=None, using=None, hints=None)[source]

Provides custom functionality pertaining to the fields provided by Auditable.

as_manager()

See MixableQuerySet.as_manager().

create(_user=None, **kwargs)[source]

Overridden to ensure a user is provided to the save() call on the model instance. The _user argument (named to reduce potential conflicts with model field names) is the user instance to pass through. It is required unless the DJEM_AUDITABLE_REQUIRE_USER_ON_SAVE setting is False.

New in version 0.7.

get_or_create(defaults=None, _user=None, **kwargs)[source]

Overridden to ensure a user is provided to the save() call on the model instance, if a record needs to be created. The _user argument (named to reduce potential conflicts with model field names) is the user instance to pass through. It is required unless the DJEM_AUDITABLE_REQUIRE_USER_ON_SAVE setting is False.

New in version 0.7.

update(_user=None, **kwargs)[source]

Overridden to ensure the user_modified and date_modified fields are always updated. The _user argument (named to reduce potential conflicts with model field names) is the user instance to update user_modified with. It is required unless the DJEM_AUDITABLE_REQUIRE_USER_ON_SAVE setting is False.

update_or_create(defaults=None, _user=None, **kwargs)[source]

Overridden to ensure a user is provided to the save() call on the model instance, whether the record id being created or updated. The _user argument (named to reduce potential conflicts with model field names) is the user instance to pass through. It is required unless the DJEM_AUDITABLE_REQUIRE_USER_ON_SAVE setting is False.

New in version 0.7.

owned_by(user)[source]

Return a queryset of records “owned” by the given user, as per the user_created field. user can be a User instance or an id.

ArchivableQuerySet

class djem.models.ArchivableQuerySet(model=None, query=None, using=None, hints=None)[source]

Provides custom functionality pertaining to the is_archived field provided by Archivable.

as_manager()

See MixableQuerySet.as_manager().

archived()[source]

Filter the queryset to archived records (is_archived=True).

New in version 0.7.

unarchived()[source]

Filter the queryset to unarchived records (is_archived=False).

New in version 0.7.

VersionableQuerySet

Changed in version 0.7: Renamed from VersioningQuerySet. The old name is still available for backwards compatibility, but is considered deprecated.

class djem.models.VersionableQuerySet(model=None, query=None, using=None, hints=None)[source]

Provides custom functionality pertaining to the version field provided by Versionable.

as_manager()

See MixableQuerySet.as_manager().

update(**kwargs)[source]

Overridden to ensure the version field is always updated.

StaticAbstract

class djem.models.StaticAbstract[source]

StaticAbstract is a combination of Auditable, Archivable and Versionable. It is designed as an abstract base class for models, rather than a mixin itself. It includes all the fields and functionality offered by each of the mixins.