Make User.generate_username less stupid

This commit is contained in:
imperosol 2024-11-18 14:01:45 +01:00
parent 9991f5dc64
commit 3b39049c20
2 changed files with 36 additions and 6 deletions

View File

@ -26,6 +26,7 @@ from __future__ import annotations
import importlib import importlib
import logging import logging
import os import os
import string
import unicodedata import unicodedata
from datetime import timedelta from datetime import timedelta
from pathlib import Path from pathlib import Path
@ -688,12 +689,20 @@ class User(AbstractBaseUser):
.encode("ascii", "ignore") .encode("ascii", "ignore")
.decode("utf-8") .decode("utf-8")
) )
un_set = [u.username for u in User.objects.all()] # load all usernames which could conflict with the new one.
if user_name in un_set: # we need to actually load them, instead of performing a count,
i = 1 # because we cannot be sure that two usernames refer to the
while user_name + str(i) in un_set: # actual same word (eg. tmore and tmoreau)
i += 1 possible_conflicts: list[str] = list(
user_name += str(i) User.objects.filter(username__startswith=user_name).values_list(
"username", flat=True
)
)
nb_conflicts = sum(
1 for name in possible_conflicts if name.rstrip(string.digits) == user_name
)
if nb_conflicts > 0:
user_name += str(nb_conflicts) # exemple => exemple1
self.username = user_name self.username = user_name
return user_name return user_name

View File

@ -166,3 +166,24 @@ def test_user_invoice_with_multiple_items():
.values_list("total", flat=True) .values_list("total", flat=True)
) )
assert res == [15, 13, 5] assert res == [15, 13, 5]
@pytest.mark.django_db
@pytest.mark.parametrize(
("first_name", "last_name", "expected"),
[
("Auguste", "Bartholdi", "abartholdi2"), # ville du lion rpz
("Aristide", "Denfert-Rochereau", "adenfertrochereau"),
("John", "Dôe", "jdoe"), # with an accent
],
)
def test_generate_username(first_name: str, last_name: str, expected: str):
baker.make(
User,
username=iter(["abar", "abartholdi", "abartholdi1", "abar1"]),
_quantity=4,
_bulk_create=True,
)
new_user = User(first_name=first_name, last_name=last_name, email="a@example.com")
new_user.generate_username()
assert new_user.username == expected