diff --git a/docs/custom.md b/docs/custom.md index 60fe9730..50d8204a 100644 --- a/docs/custom.md +++ b/docs/custom.md @@ -82,4 +82,22 @@ And so on! See also [https://github.com/etalab/cartes.data.gouv.fr](https://github.com/etalab/cartes.data.gouv.fr) -for an example of customization. +for an example of theme customization. + + +## Custom user display name + +In some situation, you may want to customize the display name of users, which +is by default the username. + +There are three settings you can play with to control that: + + # The display name itself, could be for example "{first_name} {last_name}" + USER_DISPLAY_NAME = "{username}" + # Which field to search for when autocompleting users (for permissions) + # See https://django-agnocomplete.readthedocs.io/en/latest/autocomplete-definition.html#agnocompletemode + USER_AUTOCOMPLETE_FIELDS = ["^username"] + # Which field to use in the URL, may also be for example "pk" to use the + # primary key and not expose the username (which may be private or may change too + # often for URL persistance) + USER_URL_FIELD = "username" diff --git a/umap/autocomplete.py b/umap/autocomplete.py index 6a485182..860c74f1 100644 --- a/umap/autocomplete.py +++ b/umap/autocomplete.py @@ -1,6 +1,5 @@ from django.conf import settings from django.contrib.auth import get_user_model -from django.urls import reverse from agnocomplete.register import register @@ -10,10 +9,9 @@ from agnocomplete.core import AgnocompleteModel @register class AutocompleteUser(AgnocompleteModel): model = get_user_model() - fields = ['^username'] + fields = settings.USER_AUTOCOMPLETE_FIELDS def item(self, current_item): data = super().item(current_item) - data['url'] = reverse(settings.USER_MAPS_URL, - args=(current_item.get_username(), )) + data['url'] = current_item.get_url() return data diff --git a/umap/models.py b/umap/models.py index fc9b8c40..719a6845 100644 --- a/umap/models.py +++ b/umap/models.py @@ -1,6 +1,7 @@ import os import time +from django.contrib.auth.models import User from django.contrib.gis.db import models from django.conf import settings from django.urls import reverse @@ -12,6 +13,29 @@ from django.core.files.base import File from .managers import PublicManager +# Did not find a clean way to do this in Django +# - creating a Proxy model would mean replacing get_user_model by this proxy model +# in every template +# - extending User model woulc mean a non trivial migration +def display_name(self): + return settings.USER_DISPLAY_NAME.format(**self.__dict__) + + +def get_user_url(self): + identifier = getattr(self, settings.USER_URL_FIELD) + return reverse(settings.USER_MAPS_URL, kwargs={"identifier": identifier}) + + +def get_user_stars_url(self): + identifier = getattr(self, settings.USER_URL_FIELD) + return reverse("user_stars", kwargs={"identifier": identifier}) + + +User.add_to_class("__str__", display_name) +User.add_to_class("get_url", get_user_url) +User.add_to_class("get_stars_url", get_user_stars_url) + + class NamedModel(models.Model): name = models.CharField(max_length=200, verbose_name=_("name")) diff --git a/umap/settings/base.py b/umap/settings/base.py index f4e5f192..e1c009c3 100644 --- a/umap/settings/base.py +++ b/umap/settings/base.py @@ -211,6 +211,11 @@ MIDDLEWARE = ( # Set to True if login into django account should be possible. Default is to # only use OAuth flow. ENABLE_ACCOUNT_LOGIN = env.bool("ENABLE_ACCOUNT_LOGIN", default=False) +USER_DISPLAY_NAME = "{username}" +# For use by Agnocomplete +# See https://django-agnocomplete.readthedocs.io/en/latest/autocomplete-definition.html#agnocompletemode +USER_AUTOCOMPLETE_FIELDS = ["^username"] +USER_URL_FIELD = "username" # ============================================================================= # Miscellaneous project settings @@ -252,8 +257,6 @@ LEAFLET_ZOOM = env.int('LEAFLET_ZOOM', default=6) COMPRESS_ENABLED = True COMPRESS_OFFLINE = True -SOCIAL_AUTH_DEFAULT_USERNAME = lambda u: slugify(u) -SOCIAL_AUTH_ASSOCIATE_BY_EMAIL = True SOCIAL_AUTH_NO_DEFAULT_PROTECTED_USER_FIELDS = True SOCIAL_AUTH_PROTECTED_USER_FIELDS = ("id", ) LOGIN_URL = "login" diff --git a/umap/templates/umap/login_popup_end.html b/umap/templates/umap/login_popup_end.html index 459d5547..9ea96dfc 100644 --- a/umap/templates/umap/login_popup_end.html +++ b/umap/templates/umap/login_popup_end.html @@ -9,7 +9,7 @@ window.opener.umap_proceed(); } else { // Trade off as Twitter does not allow us to access window.opener - window.location.href = '{% url "user_maps" request.user.username %}' + window.location.href = '{{ request.user.get_url }}' } } diff --git a/umap/templates/umap/map_list.html b/umap/templates/umap/map_list.html index 672aa6a8..280246de 100644 --- a/umap/templates/umap/map_list.html +++ b/umap/templates/umap/map_list.html @@ -4,7 +4,7 @@
{% map_fragment map_inst prefix=prefix page=request.GET.p %} -
{{ map_inst.name }}{% if map_inst.owner %} {% trans "by" %} {{ map_inst.owner }}{% endif %}
+
{{ map_inst.name }}{% if map_inst.owner %} {% trans "by" %} {{ map_inst.owner }}{% endif %}
{% endfor %} {% if maps.has_next %} diff --git a/umap/templates/umap/navigation.html b/umap/templates/umap/navigation.html index 58c4d8e6..139bf789 100644 --- a/umap/templates/umap/navigation.html +++ b/umap/templates/umap/navigation.html @@ -7,8 +7,8 @@