# Imports
from django.db import models
from superdjango.shortcuts import there_can_be_only_one
# Exports
__all__ = (
"DefaultMixin",
)
# Models
[docs]class DefaultMixin(models.Model):
"""Base class for implementing a "default" model.
This model supplies the methods for using the ``pre_save`` signal and to acquire the name of the field that provides
the default flag.
"""
class Meta:
abstract = True
[docs] @staticmethod
def allow_one_default(sender, **kwargs):
"""Use this when there can be only one ``is_default`` that is ``True``."""
instance = kwargs['instance']
default_flag = instance.get_default_flag_name()
# noinspection PyTypeChecker
there_can_be_only_one(sender, instance, default_flag)
[docs] @classmethod
def get_default_flag_name(cls):
"""Get the name of the field that is used to mark the record as default.
:rtype: str
"""
return "is_default"
# noinspection PyUnusedLocal
[docs] @classmethod
def get_default_rule(cls, request=None):
"""Get the rule to be applied; allow, ignore, require. Defaults to ``allow``.
:param request: If given, the rule may be determined dynamically.
:rtype: str
"""
return "allow"
[docs] @staticmethod
def require_one_default(sender, **kwargs):
"""Works like ``allow_one_default()`` but also ensures that the first record entered becomes the default."""
# noinspection PyTypeChecker
instance = kwargs['instance']
default_flag = instance.get_default_flag_name()
is_default = getattr(instance, default_flag)
if not is_default:
if sender.objects.filter(**{default_flag: True}).count() == 0:
setattr(instance, default_flag, True)
there_can_be_only_one(sender, instance, default_flag)