【问题标题】:How to create a unique random username for django?如何为 django 创建一个唯一的随机用户名?
【发布时间】:2015-02-16 01:33:41
【问题描述】:

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

为了实现这一点,我只想在输入来自非用户的条目时创建具有随机用户名的空白用户。

随机创建唯一用户名避免任何冲突的最优雅方法是什么?

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

我见过的大多数脚本只是创建一个随机字符串,但这有冲突的危险。是否有任何 Django 函数可以根据已使用的用户名创建随机用户名?

【问题讨论】:

  • 随机与增量的优点是什么?增量用户名将向您保证零冲突并保持 unqiue。
  • 你有什么理由不能只匿名
  • 如果用户以后可以使用任何用户名注册,那么“增量”解决方案将不起作用。
  • 那么那个人的名字就是 username6 + 6
  • 您可以将当前日期/时间嵌入到用户名中以确保唯一性。

标签: python django django-1.7


【解决方案1】:

不,django 没有这样的功能。所以你必须在循环中检查生成的用户名是否存在。

【讨论】:

  • 即使在 2020 年底也是如此吗?
  • 是的。即使在 2020 年底,您也必须检查生成的用户名是否存在冲突。
【解决方案2】:

我创建了一个 mixin,它根据名字、姓氏创建一个随机用户名,并确保该用户名不存在于 db User 模型中:

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多