# Imports
# from datetime import timedelta
# from django.core.exceptions import ImproperlyConfigured
from django.db import models
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
# Exports
__all__ = (
"AutoNowAddDateTimeField",
"AutoNowDateTimeField",
)
# Constants
# Fields
[docs]class AutoNowAddDateTimeField(models.DateTimeField):
"""Automatically sets the date/time to "now" when the record is created.
It uses Django's timezone utils, which returns an aware or naive datetime, depending on ``settings.USE_TZ``.
However, use of ``USE_TZ`` is strongly recommended and is the default for new Django projects.
The ``editable`` field is also set to ``False`` by default.
"""
description = _("Set the current date/time the first time the record is saved.")
[docs] def __init__(self, *args, **kwargs):
kwargs.setdefault('editable', False)
kwargs.setdefault('default', now)
super().__init__(*args, **kwargs)
[docs]class AutoNowDateTimeField(AutoNowAddDateTimeField):
"""Extends ``AutoNowAddField`` to also add the current date/time whenever the record is saved."""
description = _("Set the current date/time any time the record is saved.")
[docs] def pre_save(self, model_instance, add):
"""Get the modified date/time automatically."""
if add:
value = self._get_new_value(model_instance)
else:
value = now()
setattr(model_instance, self.attname, value)
return value
def _get_new_value(self, model_instance):
"""If an AutoAddedDateField is present, the added_dt and modified_dt will differ ever so slightly. Scan here to
handle such a situation.
:param model_instance: The current model instance.
:rtype: datetime
"""
# If the value has already been given, assume it's been manually assigned.
value = getattr(model_instance, self.attname, self.get_default())
if value != self.get_default():
return value
else:
# noinspection PyProtectedMember
for field in model_instance._meta.get_fields():
if isinstance(field, AutoNowAddDateTimeField):
return getattr(model_instance, field.name)
return now()