如何为django创建一个独特的随机用户名?

时间:2015-02-16 01:33:41

标签: python django django-1.7

我希望我的页面访问者能够创建条目而无需先注册。当他们稍后注册时,我希望他们在该会话中创建的所有内容都属于他们的用户帐户。

为了实现这一目标,我只想在制作非用户条目时创建具有随机用户名的空白用户。

创建一个随机避免碰撞的唯一用户名的最优雅方法是什么?

我是否应该创建一个生成用户名的while循环,并尝试将它们保存到数据库中,并在成功时中断,还是有更好的方法?

我见过的大多数脚本只是创建一个随机字符串,但是存在碰撞的危险。是否有任何Django函数根据已经采用的用户名创建随机用户名?

2 个答案:

答案 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)