我希望模型在创建新示例时自动生成一个随机的字母数字字符串作为其主键。
例如:
from django.db import models
class MyTemporaryObject(models.Model):
id = AutoGenStringField(lenght=16, primary_key=True)
some_filed = ...
some_other_field = ...
在我看来,这个键应该看起来像“Ay3kJaBdGfcadZdao03293”。它是非常临时的使用。如果发生冲突,我希望Django尝试一个新的键。
我想知道是否已经有了一些东西,或者一个非常简单的解决方案,我没有看到(我是相当新的Python和Django)。否则,我想做我自己的版本的models.AutoField
,这是正确的方法吗?
我已经在这里找到了如何生成密钥,所以这不是字符串的生成,我只想让它与简单的Django服务无缝地工作,而不增加代码的复杂性。
编辑:可能的解决方案?你怎么看?
id = models.CharField(unique=True, primary_key=True, default=StringKeyGenerator(), editable=False)
与
class StringKeyGenerator(object):
def __init__(self, len=16):
self.lenght = len
def __call__(self):
return ''.join(random.choice(string.letters + string.digits) for x in range(self.lenght))
我在浏览了一遍Django的文档后想到了这个方法。
4条答案
按热度按时间nhaq1z211#
在python中生成唯一字符串最简单的方法之一是使用
uuid
模块。如果你想得到字母数字输出,你也可以简单地使用base64编码:然后,您可以将此代码放在模型的
save
方法中,或使用它定义自定义模型字段。aemubtdh2#
下面是在不将该字段设为主键的情况下执行此操作的方法:
与使用字段作为主键相比,这样可以避免两个问题:
1)Django的内置关系字段需要整数键
2)Django使用数据库中主键的存在作为
save
应该更新现有记录而不是插入新记录的标志,这意味着如果主键字段发生冲突,它会悄悄地覆盖该行中的其他内容。wtlkbnrh3#
试试看:
下面的if语句是为了确保模型是可更新的。
如果没有if语句,每次重新保存模型时都将更新id字段,因此每次都将创建一个新模型
rslzwgfq4#
下面的代码片段使用Python自带的
secrets
库,处理id冲突,并在没有id冲突时继续传递完整性错误。ID
0TCKybG1qgAhRuEN
、yJariA4QN42E9aLf
、AZOMrzlkJ-RKh4dp
的示例