Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Imports
3from django.conf import settings
4from django.db import models
5from django.utils.timezone import now
6from django.utils.translation import ugettext_lazy as _
7from superdjango.shortcuts import get_user_name
8from ..audit.utils import is_audit_model
10# Exports
12__all__ = (
13 "ArchivedModel",
14)
16# Constants
18AUTH_USER_MODEL = settings.AUTH_USER_MODEL
20# Models
23class ArchivedModel(models.Model):
24 """Supports records that may be archived.
26 **Fields**
28 - ``archived_by``
29 - ``archived_dt``
30 - ``is_archived``
32 **Proper Name**
34 The ``archived_by_name`` property is also provided which attempts to return the full name of the user.
36 **Methods**
38 - ``mark_archived()``
39 - ``mark_unarchived()``
41 """
42 cached_archived_by_name = models.CharField(
43 _("archived by"),
44 blank=True,
45 help_text=_("The name of the person that archived the record."),
46 max_length=256,
47 null=True
48 )
50 archived_by = models.ForeignKey(
51 AUTH_USER_MODEL,
52 blank=True,
53 help_text=_("The user that archived the record."),
54 null=True,
55 on_delete=models.SET_NULL,
56 related_name="%(app_label)s_%(class)s_archived_records",
57 verbose_name=_("archived by")
58 )
60 archived_dt = models.DateTimeField(
61 _("archived date/time"),
62 blank=True,
63 help_text=_("Date and time the record was archived."),
64 null=True
65 )
67 is_archived = models.BooleanField(
68 _("is archived"),
69 default=False,
70 help_text=_("Indicates the record is archived.")
71 )
73 class Meta:
74 abstract = True
76 @property
77 def archived_by_name(self):
78 """Get the name of the user that archived the record.
80 :rtype: str | None
82 """
83 return self.cached_archived_by_name
85 def mark_archived(self, user, audit=True, commit=True):
86 """Mark the record as archived.
88 :param user: The user marking the record as archived.
89 :type user: AUTH_USER_MODEL
91 :param audit: Call the ``audit()`` method if this is also an audit model.
92 :type audit: bool
94 :param commit: Whether to save immediately.
95 :type commit: bool
97 .. note::
98 Mark archived changes the record only if ``archived_dt`` is ``None``. This prevents updating the user
99 or date/time if ``mark_archived()`` is called more than once.
101 """
102 if self.archived_dt is None:
103 self.cached_archived_by_name = get_user_name(user)
104 self.archived_dt = now()
105 self.is_archived = True
106 self.archived_by = user
108 self._also_update(True)
110 if audit and is_audit_model(self):
111 # noinspection PyUnresolvedReferences
112 self.audit(user, commit=False)
114 if commit:
115 self.save()
117 def mark_unarchived(self, user, audit=True, commit=True):
118 """Mark the record as un-archived.
120 :param user: The user marking the record as un-archived.
121 :type user: AUTH_USER_MODEL
123 :param audit: Call the ``audit()`` method if this is also an audit model.
124 :type audit: bool
126 :param commit: Whether to save immediately.
127 :type commit: bool
129 """
130 self.cached_archived_by_name = None
131 self.archived_dt = None
132 self.is_archived = False
133 self.archived_by = None
135 self._also_update(False)
137 if audit and is_audit_model(self):
138 # noinspection PyUnresolvedReferences
139 self.audit(user, commit=False)
141 if commit:
142 self.save()
144 def _also_update(self, archived):
145 """A callback that may be used to update other fields on the record.
147 :param archived: Indicates whether ``mark_archived()` or ``mark_unarchived()`` is making the call.
148 :type archived: bool
150 .. warning::
151 Set fields here as needed, but do *not* call ``save()``.
153 """
154 pass