Source code for dcolumn.common.model_mixins

# -*- coding: utf-8 -*-
#
# dcolumn/common/model_mixins.py
#

"""
Mixins used in Django models.
"""
__docformat__ = "restructuredtext en"

import re
import logging
from datetime import datetime
from dateutil.tz import tzutc

from django.db import models
from django.db.models import Q
from django.utils.translation import gettext_lazy as _
from django.conf import settings

from dcolumn.common import ChoiceManagerImplementation

log = logging.getLogger('dcolumns.common.model_mixins')


#
# UserModel
#
[docs]class UserModelMixin(models.Model): """ Abstract model mixin used in the model classes to provide user and creator fields. """ updater = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_("Updater"), editable=False, related_name="%(app_label)s_%(class)s_updater_related", help_text=_("The last user to update this record.")) creator = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_("Creator"), editable=False, related_name="%(app_label)s_%(class)s_creator_related", help_text=_("The user who created this record."))
[docs] class Meta: abstract = True
[docs] def save(self, *args, **kwargs): """ Save is here to assure that save is executed throughout the MRO. :param args: Positional arguments. :param kwargs: Keyword arguments. """ super(UserModelMixin, self).save(*args, **kwargs)
[docs] def updater_producer(self): """ Primary use is in an admin class to supply the updater's full name if available else the username. :rtype: String of updater's full name. """ result = self.updater.get_full_name() if not result: result = self.updater.username return result
updater_producer.short_description = _("Updater")
[docs] def creator_producer(self): """ Primary use is in an admin class to supply the creator's full name if available else the username. :rtype: String of creator's full name. """ result = self.creator.get_full_name() if not result: result = self.creator.username return result
creator_producer.short_description = _("Creator")
# # TimeModel #
[docs]class TimeModelMixin(models.Model): """ Abstract model mixin used in the model classes to supply created and updated fields. """ created = models.DateTimeField( verbose_name=_("Date Created"), help_text=_("The date and time of creation.")) updated = models.DateTimeField( verbose_name=_("Last Updated"), help_text=_("The date and time last updated."))
[docs] class Meta: abstract = True
[docs] def save(self, *args, **kwargs): """ Understands two keyword arguments, ``disable_created`` and ``disable_updated``. These arguments are used to optionally turn off the updating of the ``created`` and ``updated`` fields on the model. This can be used when migrating data into a model that already has these fields set so the original date ad times can be kept. :param args: Positional arguments. :param kwargs: Keyword arguments. """ if not kwargs.pop('disable_created', False) and self.created is None: self.created = datetime.now(tzutc()) if not kwargs.pop('disable_updated', False): self.updated = datetime.now(tzutc()) log.debug("kwargs: %s, created: %s, updated: %s", kwargs, self.created, self.updated) super(TimeModelMixin, self).save(*args, **kwargs)
# # StatusModel #
[docs]class StatusModelManagerMixin(models.Manager): """ Manager mixin for the StatusModelMixin abstract model. """
[docs] def active(self, active=True): """ Return as default only active database objects. :param active: If ``True`` return only active records else if ``False`` return non-active records. If ``None`` return all records. :type active: bool :rtype: Django query results. """ query = [] if active is not None: query.append(Q(active=active)) return self.filter(*query)
[docs]class StatusModelMixin(models.Model): """ Abstract model mixin used in the model classes to supply the active field. """ active = models.BooleanField( verbose_name=_("Active"), default=True, help_text=_("If checked the record is active."))
[docs] class Meta: abstract = True
[docs] def save(self, *args, **kwargs): """ Save is here to assure that save is executed throughout the MRO. :param args: Positional arguments. :param kwargs: Keyword arguments. """ super(StatusModelMixin, self).save(*args, **kwargs)
# # ValidateOnSaveMixin #
[docs]class ValidateOnSaveMixin(models.Model):
[docs] class Meta: abstract = True
[docs] def save(self, *args, **kwargs): """ Execute ``full_clean``. :param args: Positional arguments. :param kwargs: Keyword arguments. """ self.full_clean() super(ValidateOnSaveMixin, self).save(*args, **kwargs)