首先正如@DanielRoseman 所说,不要在default 中调用函数,您可以将default 的值设置为可调用的,这样会更好,因为它会在每次创建对象时调用函数,但是如果您在字段定义中调用它将在解释时间调用一次
unique_id = models.CharField(db_index=True, default=generate_id)
其次,我建议使用UUIDField,它会为您生成随机字符串。
为了解决您的问题,您有两种方法。生成相当长的unique_id,至少 12 个字符长,这几乎可以保证您不会发生任何冲突。或者您可以在 generate_id 函数中添加数据库检查
def generate_id(length=6):
unique_id = ''.join(random.choice(a) for i in range(length))
while Mymodel.objects.filter(unique_id=unique_id).exists():
unique_id = ''.join(random.choice(a) for i in range(length))
return unique_id
回复评论
方法中的模型可以通过self.__class__ 访问,如下例所示
class Post(models.Model):
def _generate_id(self, length=6):
unique_id = ''.join(random.choice(a) for i in range(length))
while self.__class__.objects.filter(unique_id=unique_id).exists():
unique_id = ''.join(random.choice(a) for i in range(length))
return unique_id
但如果它是方法,您将无法将其作为默认值添加到字段中,因为不会有 self 实例。但是你可以尝试使用@classmethod 装饰器。只有在实例化Field 对象之前定义了_generate_id,这才有可能,并且它只适用于@classmethods,因为在python 中类是它们自己的微小命名空间。
class Post(models.Model):
@classmethod
def _generate_id(cls, length=6):
unique_id = ''.join(random.choice(a) for i in range(length))
while cls.objects.filter(unique_id=unique_id).exists():
unique_id = ''.join(random.choice(a) for i in range(length))
return unique_id
unique_id = models.CharField(db_index=True, default=_generate_id, max_length=12)
但我本人从未在现实生活中尝试过。