我希望我的页面访问者能够创建条目而无需先注册。当他们稍后注册时,我希望他们在该会话中创建的所有内容都属于他们的用户帐户。
为了实现这一目标,我只想在制作非用户条目时创建具有随机用户名的空白用户。
创建一个随机避免碰撞的唯一用户名的最优雅方法是什么?
我是否应该创建一个生成用户名的while循环,并尝试将它们保存到数据库中,并在成功时中断,还是有更好的方法?
我见过的大多数脚本只是创建一个随机字符串,但是存在碰撞的危险。是否有任何Django函数根据已经采用的用户名创建随机用户名?
答案 0 :(得分:2)
不,django没有这样的功能。因此,您必须检查循环中是否存在生成的用户名。
答案 1 :(得分:0)
我创建了一个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)