Consistently show user's full name (where available) in reports (#6400)

Add user_display_name template filter to simplify user display code

This replaces the `{{ some_rambling_expression_evaluating_to_a_user.get_full_name|default:some_rambling_expression_evaluating_to_a_user.get_username }}` pattern used all over the place.

Display user's full name (where available) in LogEntry listings

Don't use full name if it consists of whitespace (which happens on our test user models)

release note
pull/6407/head
Matt Westcott 2020-09-23 15:46:43 +01:00
rodzic 3ab18aa901
commit 3300e3b851
18 zmienionych plików z 59 dodań i 27 usunięć

Wyświetl plik

@ -13,6 +13,7 @@ Changelog
* Remove unidecode and use anyascii in for Unicode to ASCII conversion (Robbie Mackay)
* Add `render` helper to `RoutablePageMixin` to support serving template responses according to Wagtail conventions (Andy Babic)
* Specify minimum Python version in setup.py (Vince Salvino)
* Show user's full name in report views (Matt Westcott)
* Fix: Make page-level actions accessible to keyboard users in page listing tables (Jesse Menn)
* Fix: `WAGTAILFRONTENDCACHE_LANGUAGES` was being interpreted incorrectly. It now accepts a list of strings, as documented (Karl Hobley)
* Fix: Update oEmbed endpoints to use https where available (Matt Westcott)

Wyświetl plik

@ -22,6 +22,7 @@ Other features
* Specify minimum Python version in setup.py (Vince Salvino)
* Extend treebeard's ``fix_tree`` method with the ability to non-destructively fix path issues and add a --full option to apply path fixes (Matt Westcott)
* Add support for hierarchical/nested Collections (Robert Rollins)
* Show user's full name in report views (Matt Westcott)
Bug fixes

Wyświetl plik

@ -18,7 +18,7 @@
</div>
<div class="col9">
<h1>{% block branding_welcome %}{% blocktrans %}Welcome to the {{ site_name }} Wagtail CMS{% endblocktrans %}{% endblock %}</h1>
<div class="user-name">{{ user.get_full_name|default:user.get_username }}</div>
<div class="user-name">{{ user|user_display_name }}</div>
</div>
</div>
</header>

Wyświetl plik

@ -63,7 +63,7 @@
<td valign="top">
<div class="human-readable-date" title="{{ revision.created_at|date:"d M Y H:i" }}">{% blocktrans with time_period=revision.created_at|timesince_simple %}{{ time_period }}{% endblocktrans %} </div>
{% if revision.user %}
by {{ revision.user.get_full_name|default:revision.user.get_username }}
by {{ revision.user|user_display_name }}
{% endif %}
</td>
</tr>

Wyświetl plik

@ -1,9 +1,9 @@
{% extends 'wagtailadmin/notifications/base.html' %}
{% load i18n %}
{% load wagtailadmin_tags i18n %}
{% block content %}
<p>{% blocktrans with page=revision.page|safe editor=revision.user.get_full_name|default:revision.user.get_username %}The page "{{ page }}" has been submitted for moderation by {{ editor }}.{% endblocktrans %}</p>
<p>{% blocktrans with page=revision.page|safe editor=revision.user|user_display_name %}The page "{{ page }}" has been submitted for moderation by {{ editor }}.{% endblocktrans %}</p>
<p>
{% if revision.page.is_previewable %}

Wyświetl plik

@ -1,8 +1,8 @@
{% extends 'wagtailadmin/notifications/base.txt' %}
{% load i18n %}
{% load wagtailadmin_tags i18n %}
{% block content %}
{% blocktrans with page=revision.page|safe editor=revision.user.get_full_name|default:revision.user.get_username %}The page "{{ page }}" has been submitted for moderation by {{ editor }}.{% endblocktrans %}
{% blocktrans with page=revision.page|safe editor=revision.user|user_display_name %}The page "{{ page }}" has been submitted for moderation by {{ editor }}.{% endblocktrans %}
{% if revision.page.is_previewable %}{% trans "You can preview the page here:" %} {{ settings.BASE_URL }}{% url 'wagtailadmin_pages:preview_for_moderation' revision.id %}{% endif %}
{% trans "You can edit the page here:" %} {{ settings.BASE_URL }}{% url 'wagtailadmin_pages:edit' revision.page.id %}

Wyświetl plik

@ -1,9 +1,9 @@
{% extends 'wagtailadmin/notifications/base.html' %}
{% load i18n %}
{% load wagtailadmin_tags i18n %}
{% block content %}
{% if task_state.finished_by %}
<p>{% blocktrans with title=page.get_admin_display_title workflow=workflow.name task=task.name rejector=task_state.finished_by.get_full_name|default:task_state.finished_by.get_username %}The page "{{ title }}" has been rejected during "{{ task }}" in workflow "{{ workflow }}" by {{ rejector }}.{% endblocktrans %}</p>
<p>{% blocktrans with title=page.get_admin_display_title workflow=workflow.name task=task.name rejector=task_state.finished_by|user_display_name %}The page "{{ title }}" has been rejected during "{{ task }}" in workflow "{{ workflow }}" by {{ rejector }}.{% endblocktrans %}</p>
{% else %}
<p>{% blocktrans with title=page.get_admin_display_title workflow=workflow.name task=task.name %}The page "{{ title }}" has been rejected during "{{ task }}" in workflow "{{ workflow }}".{% endblocktrans %}</p>
{% endif %}

Wyświetl plik

@ -1,9 +1,9 @@
{% extends 'wagtailadmin/notifications/base.txt' %}
{% load i18n %}
{% load wagtailadmin_tags i18n %}
{% block content %}
{% if task_state.finished_by %}
{% blocktrans with title=page.get_admin_display_title|safe workflow=workflow.name|safe task=task.name|safe rejector=task_state.finished_by.get_full_name|default:task_state.finished_by.get_username %}The page "{{ title }}" has been rejected during "{{ task }}" in workflow "{{ workflow }}" by {{ rejector }}.{% endblocktrans %}
{% blocktrans with title=page.get_admin_display_title|safe workflow=workflow.name|safe task=task.name|safe rejector=task_state.finished_by|user_display_name %}The page "{{ title }}" has been rejected during "{{ task }}" in workflow "{{ workflow }}" by {{ rejector }}.{% endblocktrans %}
{% else %}
{% blocktrans with title=page.get_admin_display_title|safe workflow=workflow.name|safe task=task.name|safe %}The page "{{ title }}" has been rejected during "{{ task }}" in workflow "{{ workflow }}".{% endblocktrans %}
{% endif %}

Wyświetl plik

@ -44,7 +44,7 @@
{% endif %}
</td>
<td>
{% include "wagtailadmin/shared/user_avatar.html" with user=entry.user username=entry.username %}
{% include "wagtailadmin/shared/user_avatar.html" with user=entry.user username=entry.user_display_name %}
</td>
<td class="updated">
<div class="human-readable-date" title="{{ entry.timestamp|date:"d M Y H:i" }}">{% blocktrans with time_period=entry.timestamp|timesince %}{{ time_period }} ago{% endblocktrans %}</div>

Wyświetl plik

@ -17,7 +17,7 @@
<h2>{% icon "clipboard-list" class_name="initial" %} {{ workflow_state.workflow.name }}</h2>
<p>
{% blocktrans with modified_by=workflow_state.requested_by.get_full_name|default:workflow_state.requested_by.get_username %}Requested by <b>{{ modified_by }}</b>{% endblocktrans %}
{% blocktrans with modified_by=workflow_state.requested_by|user_display_name %}Requested by <b>{{ modified_by }}</b>{% endblocktrans %}
<span class="avatar small"><img src="{% avatar_url workflow_state.requested_by size=25 %}" alt="" /></span>
</p>
@ -57,7 +57,7 @@
{% if not forloop.first %}
{% trans "Page edited" as action %}
{% if revision.user %}
{% blocktrans with '<b>'|add:action|add:'</b>' as action and revision.user.get_full_name|default:revision.user.get_username as who and revision.created_at as at %}
{% blocktrans with '<b>'|add:action|add:'</b>' as action and revision.user|user_display_name as who and revision.created_at as at %}
{{ action }} by <b>{{ who }}</b> at <b>{{ at }}</b>
{% endblocktrans %}
{% else %}
@ -72,7 +72,7 @@
<td>
{% if task_state.status == 'approved' or task_state.status == 'rejected' %}
{% if task_state.finished_by %}
{% blocktrans with action='<div class="status-tag primary">'|add:task_state.get_status_display|add:'</div>'|safe who=task_state.finished_by.get_full_name|default:task_state.finished_by.get_username at=task_state.finished_at %}
{% blocktrans with action='<div class="status-tag primary">'|add:task_state.get_status_display|add:'</div>'|safe who=task_state.finished_by|user_display_name at=task_state.finished_at %}
{{ action }} by <b>{{ who }}</b> at <b>{{ at }}</b>
{% endblocktrans %}
{% else %}
@ -113,7 +113,7 @@
{% elif timeline_item.action == 'page_edited' %}
{% trans "Page edited" as action %}
{% if revision.user %}
{% blocktrans with '<b>'|add:action|add:'</b>' as action and timeline_item.revision.user.get_full_name|default:timeline_item.revision.user.get_username as who %}
{% blocktrans with '<b>'|add:action|add:'</b>' as action and timeline_item.revision.user|user_display_name as who %}
{{ action }} by <b>{{ who }}</b>
{% endblocktrans %}
{% else %}
@ -123,7 +123,7 @@
<b>{{ timeline_item.task_state.task }}</b>
{% if timeline_item.task_state.finished_by %}
{% blocktrans with action='<div class="status-tag primary">'|add:timeline_item.task_state.get_status_display|add:'</div>'|safe who=timeline_item.task_state.finished_by.get_full_name|default:timeline_item.task_state.finished_by.get_username %}
{% blocktrans with action='<div class="status-tag primary">'|add:timeline_item.task_state.get_status_display|add:'</div>'|safe who=timeline_item.task_state.finished_by|user_display_name %}
{{ action }} by <b>{{ who }}</b>
{% endblocktrans %}
{% else %}

Wyświetl plik

@ -42,7 +42,7 @@
</span>
{% endfor %}
</td>
<td>{{ workflow_state.requested_by.get_full_name|default:workflow_state.requested_by.get_username }}</td>
<td>{{ workflow_state.requested_by|user_display_name }}</td>
<td>
<div class="human-readable-date" title="{{ workflow_state.created_at|date:"d M Y H:i" }}">
{% blocktrans with time_period=workflow_state.created_at|timesince %}{{ time_period }} ago{% endblocktrans %}

Wyświetl plik

@ -39,7 +39,7 @@
{{ entry|format_action_log_message }}
</td>
<td>
{% include "wagtailadmin/shared/user_avatar.html" with user=entry.user username=entry.username %}
{% include "wagtailadmin/shared/user_avatar.html" with user=entry.user username=entry.user_display_name %}
</td>
<td class="updated">
<div class="human-readable-date" title="{{ entry.timestamp|date:"d M Y H:i" }}">{% blocktrans with time_period=entry.timestamp|timesince %}{{ time_period }} ago{% endblocktrans %}</div>

Wyświetl plik

@ -64,7 +64,7 @@
</span>
{% endfor %}
</td>
<td>{{ workflow_state.requested_by.get_full_name|default:workflow_state.requested_by.get_username }}</td>
<td>{{ workflow_state.requested_by|user_display_name }}</td>
<td>{{ workflow_state.created_at }}</td>
</tr>
{% endfor %}

Wyświetl plik

@ -24,7 +24,7 @@
{% with latest_revision=page.get_latest_revision %}
{% if latest_revision %}
{% if latest_revision.user %}
<span class="avatar small" data-wagtail-tooltip="{{ latest_revision.user.get_full_name|default:latest_revision.user.get_username }}"><img src="{% avatar_url latest_revision.user size=25 %}" alt="" /></span>
<span class="avatar small" data-wagtail-tooltip="{{ latest_revision.user|user_display_name }}"><img src="{% avatar_url latest_revision.user size=25 %}" alt="" /></span>
{% endif %}
{% if latest_revision == page.live_revision %}
{% trans "Published" %}

Wyświetl plik

@ -9,7 +9,7 @@
Submitted to <em>{{ workflow_name }}</em> at {{ started_at }}
{% endblocktrans %}
{% if workflow_state.requested_by %}
{% blocktrans with modified_by=workflow_state.requested_by.get_full_name|default:workflow_state.requested_by.get_username %}by {{ modified_by }}{% endblocktrans %}
{% blocktrans with modified_by=workflow_state.requested_by|user_display_name %}by {{ modified_by }}{% endblocktrans %}
<span class="avatar small"><img src="{% avatar_url page.get_latest_revision.user size=25 %}" alt="" /></span>
{% endif %}
</p>
@ -24,7 +24,7 @@
{% icon name="warning" class_name="default" %}<strong>{{ task.name }}</strong>
{% if task.task_state.finished_by %}
{% blocktrans trimmed with requested_by=task.task_state.finished_by.get_full_name|default:task.task_state.finished_by.get_username %}
{% blocktrans trimmed with requested_by=task.task_state.finished_by|user_display_name %}
Changes requested by {{ requested_by }}
{% endblocktrans %}
{% else %}
@ -33,7 +33,7 @@
{% else %}
{% icon name="success" class_name="default" %}{{ task.name }}
{% if task.task_state.finished_by %}
{% blocktrans trimmed with approved_by=task.task_state.finished_by.get_full_name|default:task.task_state.finished_by.get_username %}
{% blocktrans trimmed with approved_by=task.task_state.finished_by|user_display_name %}
Approved by {{ approved_by }}
{% endblocktrans %}
{% endif %}

Wyświetl plik

@ -628,3 +628,24 @@ def minimum_collection_depth(collections: QuerySet) -> int:
use {% format_collection collection min_depth %}.
"""
return collections.aggregate(Min('depth'))['depth__min'] or 2
@register.filter
def user_display_name(user):
"""
Returns the preferred display name for the given user object: the result of
user.get_full_name() if implemented and non-empty, or user.get_username() otherwise.
"""
try:
full_name = user.get_full_name().strip()
if full_name:
return full_name
except AttributeError:
pass
try:
return user.get_username()
except AttributeError:
# we were passed None or something else that isn't a valid user object; return
# empty string to replicate the behaviour of {{ user.get_full_name|default:user.get_username }}
return ''

Wyświetl plik

@ -4151,16 +4151,25 @@ class BaseLogEntry(models.Model):
)
@cached_property
def username(self):
def user_display_name(self):
"""
Returns the associated username. Defaults to 'system' when none is provided
Returns the display name of the associated user;
get_full_name if available and non-empty, otherwise get_username.
Defaults to 'system' when none is provided
"""
if self.user_id:
try:
return self.user.get_username()
user = self.user
except self._meta.get_field('user').related_model.DoesNotExist:
# User has been deleted
return _('user %(id)d (deleted)') % {'id': self.user_id}
try:
full_name = user.get_full_name().strip()
except AttributeError:
full_name = ''
return full_name or user.get_username()
else:
return _('system')

Wyświetl plik

@ -35,7 +35,7 @@
<td class="title" valign="top">
<div class="title-wrapper">
<span class="avatar small"><img src="{% avatar_url user size=25 %}" alt="" /></span>
<a href="{% url 'wagtailusers_users:edit' user.pk %}">{{ user.get_full_name|default:user.get_username }}</a>
<a href="{% url 'wagtailusers_users:edit' user.pk %}">{{ user|user_display_name }}</a>
</div>
<ul class="actions">
{% user_listing_buttons user %}