254 lines
5.7 KiB
Python
254 lines
5.7 KiB
Python
# from django.db import models
|
|
from django.conf import settings
|
|
from django.core.exceptions import (
|
|
ValidationError
|
|
)
|
|
|
|
from rest_framework.reverse import reverse
|
|
|
|
from access.models.tenancy_abstract import TenancyAbstractModel
|
|
|
|
|
|
class CenturionMethodstoMigrate(
|
|
TenancyAbstractModel,
|
|
# models.Model
|
|
):
|
|
""" Centurion Model
|
|
|
|
This class exists containing new objects that will move to class `CenturionModel`
|
|
when they are ready.
|
|
"""
|
|
|
|
_audit_enabled: bool = True
|
|
"""Should this model have audit history kept"""
|
|
|
|
_is_submodel: bool = False
|
|
"""This model a sub-model"""
|
|
|
|
_notes_enabled: bool = True
|
|
"""Should a table for notes be created for this model"""
|
|
|
|
context: dict = {
|
|
'logger': None,
|
|
'request': None,
|
|
}
|
|
""" Model Context
|
|
|
|
**ToDo:** Drop request and add user when user model refactored with tenancy.
|
|
|
|
Context for actions within the model.
|
|
"""
|
|
|
|
|
|
|
|
def clean_fields(self, exclude=None) -> None:
|
|
|
|
super().clean_fields(exclude = exclude)
|
|
|
|
|
|
|
|
def delete(self, using = None, keep_parents = _is_submodel):
|
|
"""Delete Centurion Model
|
|
|
|
If a model has `_audit_enabled = True`, audit history is populated and
|
|
ready to be saved by the audit system (save signal.).
|
|
|
|
Args:
|
|
using (_type_, optional): _description_. Defaults to None.
|
|
keep_parents (bool, optional): Keep parent models. Defaults to the
|
|
value if is_submodel so as not to delete parent models.
|
|
"""
|
|
|
|
if self._audit_enabled:
|
|
|
|
self._after = {}
|
|
|
|
self._before = self.__class__.objects.get( id = self.id ).get_audit_values()
|
|
|
|
|
|
super().delete(using = using, keep_parents = keep_parents)
|
|
|
|
|
|
|
|
def full_clean(self, exclude = None, validate_unique = True, validate_constraints = True) -> None:
|
|
|
|
super().full_clean(
|
|
exclude = exclude,
|
|
validate_unique = validate_unique,
|
|
validate_constraints = validate_constraints
|
|
)
|
|
|
|
|
|
def get_audit_values(self) -> dict:
|
|
"""Retrieve the field Values
|
|
|
|
Currently ensures only fields are present.
|
|
|
|
**ToDo:** Update so the dict that it returns is a dict of dict where each dict
|
|
is named after the actual models the fields come from and it contains
|
|
only it's fields.
|
|
|
|
Returns:
|
|
dict: Model fields
|
|
"""
|
|
|
|
if self.id is None:
|
|
return {}
|
|
|
|
|
|
data = self.__dict__.copy()
|
|
|
|
clean_data: dict = {}
|
|
|
|
for name, data in data.items():
|
|
|
|
for field in self._meta.fields:
|
|
|
|
if name == field.name:
|
|
|
|
clean_data.update({
|
|
name: data
|
|
})
|
|
|
|
break
|
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
def get_after(self) -> dict:
|
|
"""Audit Data After Change
|
|
|
|
Returns:
|
|
dict: All model fields after the data changed
|
|
"""
|
|
return self._after
|
|
|
|
|
|
|
|
def get_before(self) -> dict:
|
|
"""Audit Data Before Change
|
|
|
|
Returns:
|
|
dict: All model fields before the data changed
|
|
"""
|
|
return self._before
|
|
|
|
|
|
|
|
def get_url( self, relative: bool = False, api_version: int = 2 ) -> str:
|
|
"""Return the models API URL
|
|
|
|
Args:
|
|
relative (bool, optional): Return the relative URL for the model. Defaults to False.
|
|
api_version (int, optional): API Version to use. Defaults to `2``.
|
|
|
|
Returns:
|
|
str: API URL for the model
|
|
"""
|
|
|
|
namespace = f'v{api_version}'
|
|
|
|
url_basename = f'{namespace}:_api_{self._meta.model_name}-detail'
|
|
|
|
url = reverse( viewname = url_basename, kwargs = { 'pk': self.id } )
|
|
|
|
if relative:
|
|
|
|
url = settings.SITE_URL + url
|
|
|
|
|
|
return url
|
|
|
|
|
|
|
|
def save(self, force_insert = False, force_update = False, using = None, update_fields = None):
|
|
"""Save Centurion Model
|
|
|
|
This Save ensures that `full_clean()` is called so that prior to the
|
|
model being saved to the database, it is valid.
|
|
|
|
If a model has `_audit_enabled = True`, audit history is populated and
|
|
ready to be saved by the audit system (save signal.).
|
|
"""
|
|
|
|
self.full_clean(
|
|
exclude = None,
|
|
validate_unique = True,
|
|
validate_constraints = True
|
|
)
|
|
|
|
if self._audit_enabled:
|
|
|
|
self._after = self.get_audit_values()
|
|
|
|
self._before = {}
|
|
|
|
if self.id:
|
|
|
|
self._before = self.__class__.objects.get( id = self.id ).get_audit_values()
|
|
|
|
|
|
super().save(force_insert=force_insert, force_update=force_update, using=using, update_fields=update_fields)
|
|
|
|
|
|
|
|
def validate_constraints(self, exclude = None) -> None:
|
|
|
|
super().validate_constraints(exclude = exclude)
|
|
|
|
|
|
|
|
|
|
class CenturionModel(
|
|
# TenancyAbstractModel,
|
|
# models.Model
|
|
):
|
|
|
|
|
|
|
|
_audit_enabled: bool = True
|
|
"""Should this model have audit history kept"""
|
|
|
|
_is_submodel: bool = False
|
|
"""This model a sub-model"""
|
|
|
|
|
|
class Meta:
|
|
|
|
abstract = True
|
|
|
|
|
|
@staticmethod
|
|
def validate_field_not_none(value):
|
|
|
|
if value is None:
|
|
|
|
raise ValidationError(code = 'field_value_not_none', message = 'Value can not be none.')
|
|
|
|
|
|
|
|
def get_history_model_name(self) -> str:
|
|
"""Get the name for the History Model
|
|
|
|
Returns:
|
|
str: Name of the history model (`<model class name>AuditHistory`)
|
|
"""
|
|
|
|
return f'{self._meta.object_name}AuditHistory'
|
|
|
|
|
|
|
|
class CenturionSubModel(
|
|
CenturionModel
|
|
):
|
|
|
|
_is_submodel: bool = True
|
|
"""This model a sub-model"""
|
|
|
|
|
|
class Meta:
|
|
|
|
abstract = True
|