我知道id本身是独一无二的,我想创建一个更长,更不易猜测的独特字段。简而言之,该字段将是一个唯一的21个字符的字母数字字符串。我这样做是使用以下代码:
class Organization(models.Model):
name = models.CharField(max_length=255)
key = models.CharField(max_length=21, unique=True, blank=True, null=True)
def save(self, *args, **kwargs):
if self.key == '' or self.key == None:
key = ''
for i in range(21):
key += random.choice(string.lowercase + string.uppercase + string.digits)
if Organization.objects.filter(key=key).exists():
self.save() # Try again
else:
self.key = key
super(Organization, self).save(*args, **kwargs)
在save
方法中,我执行以下操作:
这是正确的方法吗?
是否有更好的方法可能会少用代码?另外,请注意我的关键字段是如何唯一的,但也可以是空白的。这可能是个问题吗?到目前为止,这已经很好了。任何帮助表示赞赏。
答案 0 :(得分:2)
现在,您似乎正在尝试使用CharField
模拟UUID(通用唯一标识符)。虽然这种方法可能不会引起太多问题(它确实提供了(26 + 26 + 10)** 21种可能的组合),但这是一种非常天真的方法。
为什么不使用Django的原生UUIDField
?这是一个例子:
class Organization(models.Model):
name = models.CharField(max_length=255)
key = models.UUIDField(default=uuid.uuid4, editable=False)
这将使用uuid
Python模块。它将生成一个随机的UUID:
In [1]: uuid.uuid4()
Out[1]: UUID('3be0e5db-eb0a-4f09-bda3-37006760ab38')
In [2]: uuid.uuid4()
Out[2]: UUID('8d916804-0a53-478e-8e4f-ebda5d7a69ab')
显然,这些UUID是十六进制的并且包含连字符,但我认为最好遵循这个约定而不是定义自己的唯一标识符。
答案 1 :(得分:0)
你可以uuid4。但我个人更喜欢CharField并将uuid4字符指定为默认值。原因是UUIDField在查询DB时会带来很多不便。
通过将uuid代码分配给默认值,如下所示,
from django.db import models
import uuid
class Person(models.Model):
name = models.CharField(max_length=255)
code = models.CharField(max_length=8, unique=True, default=uuid.uuid4)