如何为 Django 创建一个唯一的随机用户名?
How to create a unique random username for django?
我希望我页面的访问者无需先注册即可创建条目。当他们稍后注册时,我希望他们在该会话中创建的所有内容都属于他们的用户帐户。
为了实现这一点,我只想在非用户输入时创建具有随机用户名的空白用户。
随机创建唯一用户名避免任何冲突的最优雅方法是什么?
我应该做一个 while 循环来生成用户名并在成功时尝试将它们保存到数据库中,还是有更好的方法?
我见过的大多数脚本只是创建一个随机字符串,但这有发生冲突的危险。是否有任何 Django 函数可以根据已使用的用户名创建随机用户名?
不,django 没有这样的功能。所以你必须在循环中检查生成的用户名是否存在。
我创建了一个 mixin,它根据名字、姓氏创建一个随机用户名,并确保该用户名不存在于数据库用户模型中:
random_username_mixin.py
import random
import string
from core.models import CustomUser
class RandomUsernameMixin:
"""
using firstname & lastname
create a random username (all lower case)
that doesnt already exist in db
"""
num_of_random_letters = 3
num_of_random_numbers = 2
user_model = CustomUser
def get_username(self, firstname=None, lastname=None):
username = ''
if firstname and lastname \
and firstname != '' and lastname != '':
username = firstname[0] + lastname[0]
while True:
random_letters = string.ascii_lowercase
random_numbers = string.digits
username += self.get_random_char(
random_letters, self.num_of_random_letters
)
username += self.get_random_char(
random_numbers, self.num_of_random_numbers
)
if self.username_exist_in_db(username) is False:
return username
def username_exist_in_db(self, username):
"""
:return: True if username already exist in db
else False
"""
q = self.user_model.objects.filter(username=username)
return q.exists()
def get_random_char(self, ip_str, n):
return (''.join(
random.choice(ip_str)
for i in range(n)
))
以下为测试代码。它测试上面的代码:
test_random_username_mixin.py
from django.test import TestCase
from miscellaneous.mixins.random_username_mixin import RandomUsernameMixin
class TestRandomUsernameMixin(RandomUsernameMixin,
TestCase):
def test_username_with_fn_ln(self):
fn = 'aseem'
ln = 'hegshetye'
username = self.get_username(
firstname=fn, lastname=ln
)
len_of_initials = 2
len_of_username = self.num_of_random_numbers + \
self.num_of_random_letters + \
len_of_initials
self.assertEqual(len(username), len_of_username)
print(username)
def test_username_without_fn_ln(self):
username = self.get_username()
len_of_initials = 0
len_of_username = self.num_of_random_numbers + \
self.num_of_random_letters + \
len_of_initials
self.assertEqual(len(username), len_of_username)
print(username)
我希望我页面的访问者无需先注册即可创建条目。当他们稍后注册时,我希望他们在该会话中创建的所有内容都属于他们的用户帐户。
为了实现这一点,我只想在非用户输入时创建具有随机用户名的空白用户。
随机创建唯一用户名避免任何冲突的最优雅方法是什么?
我应该做一个 while 循环来生成用户名并在成功时尝试将它们保存到数据库中,还是有更好的方法?
我见过的大多数脚本只是创建一个随机字符串,但这有发生冲突的危险。是否有任何 Django 函数可以根据已使用的用户名创建随机用户名?
不,django 没有这样的功能。所以你必须在循环中检查生成的用户名是否存在。
我创建了一个 mixin,它根据名字、姓氏创建一个随机用户名,并确保该用户名不存在于数据库用户模型中:
random_username_mixin.py
import random
import string
from core.models import CustomUser
class RandomUsernameMixin:
"""
using firstname & lastname
create a random username (all lower case)
that doesnt already exist in db
"""
num_of_random_letters = 3
num_of_random_numbers = 2
user_model = CustomUser
def get_username(self, firstname=None, lastname=None):
username = ''
if firstname and lastname \
and firstname != '' and lastname != '':
username = firstname[0] + lastname[0]
while True:
random_letters = string.ascii_lowercase
random_numbers = string.digits
username += self.get_random_char(
random_letters, self.num_of_random_letters
)
username += self.get_random_char(
random_numbers, self.num_of_random_numbers
)
if self.username_exist_in_db(username) is False:
return username
def username_exist_in_db(self, username):
"""
:return: True if username already exist in db
else False
"""
q = self.user_model.objects.filter(username=username)
return q.exists()
def get_random_char(self, ip_str, n):
return (''.join(
random.choice(ip_str)
for i in range(n)
))
以下为测试代码。它测试上面的代码:
test_random_username_mixin.py
from django.test import TestCase
from miscellaneous.mixins.random_username_mixin import RandomUsernameMixin
class TestRandomUsernameMixin(RandomUsernameMixin,
TestCase):
def test_username_with_fn_ln(self):
fn = 'aseem'
ln = 'hegshetye'
username = self.get_username(
firstname=fn, lastname=ln
)
len_of_initials = 2
len_of_username = self.num_of_random_numbers + \
self.num_of_random_letters + \
len_of_initials
self.assertEqual(len(username), len_of_username)
print(username)
def test_username_without_fn_ln(self):
username = self.get_username()
len_of_initials = 0
len_of_username = self.num_of_random_numbers + \
self.num_of_random_letters + \
len_of_initials
self.assertEqual(len(username), len_of_username)
print(username)