Commit ed95aa36 authored by Daniel Klaffenbach's avatar Daniel Klaffenbach 🐍

Remove post_save hacks from middleware and use thread local storage

parent f9ea424b
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
USERNAME_MODEL_FIELD = '_journal_entry_username'
from threading import local
_thread_local_storage = local()
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db.models import signals
from django.utils.functional import curry
from . import USERNAME_MODEL_FIELD
from . import _thread_local_storage
class ModelJournalMiddleware(object):
def process_request(self, request):
if not request.method in ('GET', 'HEAD', 'OPTIONS', 'TRACE'):
if hasattr(request, 'user') and request.user.is_authenticated():
user = request.user
username = getattr(user, user.USERNAME_FIELD)
else:
username = ''
username = ''
if hasattr(request, 'user') and request.user.is_authenticated():
user = request.user
username = getattr(user, user.USERNAME_FIELD)
set_pre_save_attrs = curry(self._set_pre_save_info, username)
signals.pre_save.connect(set_pre_save_attrs, dispatch_uid =(self.__class__, request,), weak=False)
_thread_local_storage.model_journal_username = username
def process_response(self, request, response):
signals.pre_save.disconnect(dispatch_uid=(self.__class__, request,))
_thread_local_storage.model_journal_username = ''
return response
def _set_pre_save_info(self, username, sender, instance, **kwargs):
if hasattr(sender, 'get_log_entry_username'):
setattr(instance, USERNAME_MODEL_FIELD, username)
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from getpass import getuser
import logging
......@@ -9,12 +10,12 @@ from django.core.exceptions import ImproperlyConfigured
from django.db import models
from django.db.models import Q
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _, ugettext
from jsonfield import JSONField
from . import USERNAME_MODEL_FIELD
from django.utils.formats import date_format
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _, ugettext
from jsonfield import JSONField
from . import _thread_local_storage
logger = logging.getLogger(__name__)
......@@ -189,6 +190,8 @@ class Journal(GenericRelation):
def contribute_to_class(self, cls, name):
super(Journal, self).contribute_to_class(cls, name)
# Monkey-patch the model class if it does not define a
# `get_journal_entry_username` method.
if not hasattr(cls, 'get_journal_entry_username'):
setattr(cls, 'get_journal_entry_username', get_journal_entry_username)
else:
......@@ -230,8 +233,18 @@ class Journal(GenericRelation):
def get_journal_entry_username(self):
"""
This function will become a member of all models which have a `Journal`
relation defined, unless a method with the same name already exists on
that model.
In the latter case it is possible to override the username, in case you
do not want to rely on thread-local storage. For example, if you already
keep track of the modifying user in your model, you could reuse this
information for the model journal.
"""
try:
return getattr(self, USERNAME_MODEL_FIELD)
return getattr(_thread_local_storage, 'model_journal_username')
except AttributeError:
if 'model_journal.middleware.ModelJournalMiddleware' not in settings.MIDDLEWARE_CLASSES:
raise ImproperlyConfigured(
......@@ -239,5 +252,5 @@ def get_journal_entry_username(self):
)
else:
username = getuser()
logger.info("Using current system user (%s) for ModelJournal logging." %username)
logger.debug("Using current system user (%s) for ModelJournal logging." %username)
return username
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment