【发布时间】:2013-12-21 22:49:03
【问题描述】:
我希望模型在创建新实例时自动生成随机字母数字字符串作为其主键。
示例:
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 版本,那会是正确的方法吗?
我已经找到了如何生成密钥here,所以不是关于字符串生成的。我只想让它与一个简单的 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 文档后想到的。
【问题讨论】:
-
这个的用例是什么?很多 Django 特性都假设一个整数主键,最值得注意的是外键字段。我不会说这绝不是一个好主意,但我认为您可能会发现将自动生成的字符串用作另一个字段并设置
unique=True会更简单。 -
这是一个临时令牌,用于访问更“隐藏”的数据。访问窗口很短,因此我对避免碰撞的需求大大减少了。
-
(题外话)具有单个
__call__方法的类称为函数,可以更简洁地编写:def generate_string(length): ''.join(...) -
你试过使用
default=StringKeyGenerator,不带括号吗?这样,you pass a callable as the attribute,就像 Django 文档中的 UUIDField 示例代码一样。
标签: python django postgresql