Есть множество решений, одно из них, например, переопределить, save_model для admin.ModelAdmin, но можно пойти и другим путем, переопределив save самой модели.
Это немного не в стиле Django, но на мой взгляд является самым элегантным способом.
Сперва создаем класс, который будет перехватывать request.
import threading
class CrequestMiddleware(object):
_request = {}
def process_request(self, request):
self.__class__.set_request(request)
def process_response(self, request, response):
self.__class__.del_request()
return response
def process_exception(self, request, exception):
self.__class__.del_request()
@classmethod
def get_request(cls, default=None):
return cls._request.get(threading.current_thread(), default)
дд
@classmethod
def set_request(cls, request):
cls._request[threading.current_thread()] = request
@classmethod
def del_request(cls):
cls._request.pop(threading.current_thread(), None)
Затем, создаем абстрактный класс Модели
class KernelModel(models.Model):
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, editable=False, related_name="unit_%(class)s_created_related", blank=True, null=True)
modified_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, editable=False, related_name="unit_%(class)s_modified_related", blank=True, null=True)
created_date = models.DateTimeField(_('Дата создания'), auto_now=True)
modified_date = models.DateTimeField(_('Дата изменения'), auto_now_add=True)
class Meta:
abstract = True
def save(self, *args, **kwargs):
request = CrequestMiddleware.get_request()
if hasattr(request, '_cached_user'):
user = get_user_model().objects.get(email=CrequestMiddleware.get_request()._cached_user)
if not self.created_by:
self.created_by = user
self.modified_by = user
super(KernelModel, self).save(*args, **kwargs)
Как видите, такое решение позволит при наследовании уже от KernelModel создавать модели отвечающие нашей задачи, без необходимости дальнейших правок с нашей стороны во что-нибудь еще.