hobo/hobo/user_name/apps.py

62 lines
2.1 KiB
Python

import functools
import logging
import django.db
import django.template.exceptions
from django.apps import AppConfig
from django.conf import settings
from django.contrib.auth import get_user_model
from django.template import engines
logger = logging.getLogger(__name__)
def get_full_name(user):
from hobo.agent.common.models import UserExtraAttributes
context = {}
context['user'] = user
template_vars = getattr(settings, 'TEMPLATE_VARS', {})
if 'user_full_name_template' in template_vars:
try:
template = engines['django'].from_string(template_vars['user_full_name_template'])
return template.render(context)
except django.template.exceptions.TemplateSyntaxError:
logger.exception('hobo.user_name: syntax error in inline user name template var')
except UserExtraAttributes.DoesNotExist:
logger.exception('hobo.user_name: inline user name template refers to nonexistent attribute')
return user.original_get_full_name()
def cached_extra_attributes(user):
try:
return user.extra_attributes.data
except django.db.models.ObjectDoesNotExist:
return {}
class UserNameConfig(AppConfig):
name = 'hobo.user_name'
label = 'hobo_user_name'
verbose_name = 'Hobo User Name'
def ready(self):
"""
We monkey-patch AUTH_USER_MODEL()
to ensure consistency in the rendering of user name
in the front-office, backoffice, emails, etc.
"""
logger.info('hobo.user_name: installing User.get_full_name customization…')
User = get_user_model()
# to have a fallback when necessary if the new method crashes during render
User.original_get_full_name = User.get_full_name
# to replace the rendering everywhere in a consistent manner
User.get_full_name = get_full_name
# to avoid performance/recursion issues
User.__str__ = User.original_get_full_name
if 'attributes' not in User.__dict__:
User.attributes = functools.cached_property(cached_extra_attributes)
User.attributes.__set_name__(User, 'attributes')