user: allow customization of User.get_full_name() through templates (#72945)
gitea-wip/hobo/pipeline/pr-main There was a failure building this commit Details

This commit is contained in:
Agate 2023-01-04 12:05:56 +01:00
parent a917ec7fec
commit efd605875b
6 changed files with 112 additions and 1 deletions

View File

59
hobo/user_name/apps.py Normal file
View File

@ -0,0 +1,59 @@
import functools
import logging
import django.db
import django.template.exceptions
from django.apps import AppConfig
from django.contrib.auth import get_user_model
from . import utils
logger = logging.getLogger(__name__)
def get_full_name(user):
from hobo.agent.common.models import UserExtraAttributes
try:
return user.get_full_name_from_template()
except (
# There may have been an issue during provisionning
UserExtraAttributes.DoesNotExist,
# In case some templates are missing or invalid
django.template.exceptions.TemplateDoesNotExist,
django.template.exceptions.TemplateSyntaxError,
) as e:
logger.exception('hobo.user_name: cannot render user "%s" name', user)
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 customisation…')
User = get_user_model()
# for explicit access
User.get_full_name_from_template = utils.get_full_name_from_template
# 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
# for easier access in templates
User.cached_extra_attributes = functools.cached_property(cached_extra_attributes)
User.cached_extra_attributes.__set_name__(User, 'cached_extra_attributes')

9
hobo/user_name/utils.py Normal file
View File

@ -0,0 +1,9 @@
import django.template
def get_full_name_from_template(user):
template_name = 'includes/user-info-user-name.html'
template = django.template.loader.get_template(template_name)
context = {}
context['user'] = user
return template.render(context)

View File

@ -5,7 +5,7 @@ import hobo.test_utils
LANGUAGE_CODE = 'en-us'
BROKER_URL = 'memory://'
INSTALLED_APPS += ('hobo.agent.common',)
INSTALLED_APPS += ('hobo.agent.common', 'hobo.user_name.apps.UserNameConfig')
ALLOWED_HOSTS.append('localhost')

View File

@ -0,0 +1 @@
{{ user.first_name }} {{ user.cached_extra_attributes.foo }}

42
tests/test_user_name.py Normal file
View File

@ -0,0 +1,42 @@
import os
import pytest
from django.contrib.auth.models import User
from hobo.agent.common.models import UserExtraAttributes
TESTS_DIR = os.path.dirname(os.path.abspath(__file__))
@pytest.fixture
def user(db):
u = User.objects.create(
first_name='Jane',
last_name='Doe',
)
UserExtraAttributes.objects.create(user=u, data={'foo': 'bar'})
return u
def test_user_original_get_full_name(user):
assert user.original_get_full_name() == 'Jane Doe'
def test_user_cached_extra_attributes(user):
assert user.cached_extra_attributes == {'foo': 'bar'}
def test_user_cached_extra_attributes_missing_fallbacks_to_empty_dict(user):
user.extra_attributes.delete()
user.refresh_from_db()
assert user.cached_extra_attributes == {}
def test_user_get_full_name_from_template(user, settings):
settings.TEMPLATES[0]['DIRS'] = [os.path.join(TESTS_DIR, 'templates')]
assert user.get_full_name_from_template() == 'Jane bar'
def test_user_get_full_name(user, settings):
settings.TEMPLATES[0]['DIRS'] = [os.path.join(TESTS_DIR, 'templates')]
assert user.get_full_name() == 'Jane bar'