usernames: корректная транслитерация украинских букв в логинах

pytils (русская либа) выбрасывала і/ї/є/ґ/апостроф целиком: Кіт→kt,
Філіпʼєв→flpv, Ірина→rina. Добавлен премаппинг украинских букв в латиницу
до slugify (translit_login), общий для найма, импорта и конвертации.

Теперь: Кіт Ірина → i.kit, Філіпʼєв Дмитро → d.filipiev, Ґудзик → gudzik.

- apps/hiring/services: translit_login + _username_base через него
- import_employees_json: переиспользует _username_base
- tests: украинская транслитерация в convert_usernames

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-09-21 23:39:33 +03:00
parent 33fdf8fa20
commit 626aeebbb7
3 changed files with 31 additions and 6 deletions
@@ -57,10 +57,9 @@ DEPT_73_NAME_TO_CODE = {
def transliterate_username(last_name, first_name, taken):
from pytils.translit import slugify
# Формат: <первая буква имени>.<фамилия> (Иван Иванов -> i.ivanov).
ln, fn = slugify(last_name), slugify(first_name)
base = f'{fn[:1]}.{ln}'.strip('.') or 'user'
from apps.hiring.services import _username_base
base = _username_base(last_name, first_name)
username = base
counter = 1
while username in taken or Employee.objects.filter(username=username).exists():
+12
View File
@@ -70,6 +70,18 @@ class ConvertUsernamesTests(TestCase):
self.assertEqual(a.username, 'keepme') # исключён по логину
self.assertEqual(b.username, 'petrov.s') # исключён по email
def test_ukrainian_transliteration(self):
cases = {
'kit.old': ('Ірина', 'Кіт', 'i.kit'),
'flp.old': ('Дмитро', 'Філіпʼєв', 'd.filipiev'),
'gud.old': ('Ганна', 'Ґудзик', 'g.gudzik'),
}
objs = {u: emp(u, first, last) for u, (first, last, _) in cases.items()}
self._run(apply=True)
for u, (_first, _last, expected) in cases.items():
objs[u].refresh_from_db()
self.assertEqual(objs[u].username, expected)
def test_excluded_username_is_reserved(self):
# исключённый занимает 'p.petrov' — переименовываемый получит суффикс
kept = emp('p.petrov', 'Павел', 'Петров', is_superuser=True)