Source code for django_utils.base_models
from typing import TYPE_CHECKING, Any
from django.db import models
from django.db.models import base
from django.template import defaultfilters
from python_utils import formatters
[docs]
class ModelBase(models.Model, metaclass=ModelBaseMeta):
[docs]
class CreatedAtModelBase(ModelBase):
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
[docs]
class NameMixin:
"""Mixin to automatically get a unicode and repr string base on the name
>>> x = NameMixin()
>>> x.pk = 123
>>> x.name = 'test'
>>> repr(x)
'<NameMixin[123]: test>'
>>> str(x)
'test'
>>> str(str(x))
'test'
"""
if TYPE_CHECKING:
pk: Any
name: Any
def __unicode__(self) -> str:
return self.name
def __str__(self) -> str:
return self.__unicode__()
def __repr__(self) -> str:
return f'<{self.__class__.__name__}[{self.pk or -1:d}]: {self.name}>'
[docs]
class SlugMixin(NameMixin):
"""Mixin to automatically slugify the name and add both a name and slug to
the model
>>> x = NameMixin()
>>> x.pk = 123
>>> x.name = 'test'
>>> repr(x)
'<NameMixin[123]: test>'
>>> str(x)
'test'
>>> str(str(x))
'test'
"""
if TYPE_CHECKING:
slug: Any
[docs]
def save(self, *args: Any, **kwargs: Any) -> None:
if not self.slug and self.name:
self.slug = defaultfilters.slugify(self.name)
# `save` isn't defined on NameMixin/object; it's provided by the
# concrete Model subclass this mixin is combined with at runtime
# (e.g. SlugModelBase). mypy can't see that cooperative-mixin MRO
# when checking SlugMixin in isolation.
super(NameMixin, self).save( # type: ignore[misc] # ty: ignore[unresolved-attribute]
*args, **kwargs
)
[docs]
class NameModelBase(NameMixin, ModelBase):
name = models.CharField(max_length=100)
[docs]
class SlugModelBase(SlugMixin, NameModelBase):
slug = models.SlugField(max_length=50)
[docs]
class NameCreatedAtModelBase(NameModelBase, CreatedAtModelBase):
[docs]
class SlugCreatedAtModelBase(SlugModelBase, CreatedAtModelBase):