我有一个像这样的代码生成器:
def id_generator(size=4, chars=string.ascii_uppercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
有一个像这样的Django模型:
from .extra_funcs import id_generator
def generator(digit):
ret = id_generator(digit)
return ret
class Service(models.Model):
business = models.ForeignKey(Business)
sub_service = models.ForeignKey('self', blank=True, null=True, related_name='sub_services')
code = models.CharField(max_length=20, default=generator(6), blank=False, editable=False)
en_title = models.CharField(max_length=50, blank=False)
update = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
我不知道为什么它不会产生新值,它每次只返回一次值!我该怎么办?
答案 0 :(得分:2)
你需要传递一个callable作为默认值,而不是调用callable:
from .extra_funcs import id_generator
def generator:
ret = id_generator(6)
return ret
class Service(models.Model):
business = models.ForeignKey(Business)
sub_service = models.ForeignKey('self', blank=True, null=True, related_name='sub_services')
code = models.CharField(max_length=20, default=generator, blank=False, editable=False)
en_title = models.CharField(max_length=50, blank=False)
update = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
答案 1 :(得分:1)
Django检查default
是否可调用。
generator(6)
不可调用,因为返回值和此值被指定为默认值。
尝试lambda
:
default=lambda: generator(6)
您无需定义generator
功能
default=lambda: id_generator(6)
不幸的是,不推荐这样做,因为lambda无法通过迁移进行序列化。见https://docs.djangoproject.com/en/dev/ref/models/fields/#default(感谢@knbk)
答案 2 :(得分:1)
您不能拥有default=function(value)
,只能在第一个读取解析周期立即执行语句default=function
。
所以你不能传递一个可调用的。以下是如何重写代码的方法:
from .extra_funcs import id_generator
def generator():
digit = 6
ret = id_generator(digit)
return ret
class Service(models.Model):
business = models.ForeignKey(Business)
sub_service = models.ForeignKey('self', blank=True, null=True, related_name='sub_services')
code = models.CharField(max_length=20, default=generator, blank=False, editable=False)
en_title = models.CharField(max_length=50, blank=False)
update = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)