Django:字段默认值来自模型实例
我该如何让一个字段的默认值从已有的模型对象中获取呢?
我尝试了以下几种方法,但都没有成功:
1)
class ModelA(models.Model):
fieldA = models.CharField(default=self.get_previous())
def get_previous(self):
return ModelA.objects.all()[0].fieldA
NameError: name 'self' is not defined
2)
class ModelA(models.Model):
fieldA = models.CharField(default=ModelA.get_previous())
@staticmethod
def get_previous():
return ModelA.objects.all()[0].fieldA
NameError: name 'ModelA' is not defined
3)
class ModelA(models.Model):
fieldA = models.CharField(default=get_previous())
def get_previous():
return ModelA.objects.all()[0].fieldA
NameError: global name 'get_previous' is not defined
4)
def get_previous():
return ModelA.objects.all()[0].fieldA
class ModelA(models.Model):
fieldA = models.CharField(default=get_previous())
NameError: global name 'ModelA' is not defined
很明显,为什么第3和第4种方法不行。我能理解为什么第1种方法不行——看起来类的属性不能引用实例的属性(也就是self)。我也能理解为什么第2种方法不行——显然在解释器遍历整个类之前,没有对ModelA的引用。
那么我该怎么做呢?
4 个回答
3
如果你想要输出默认值,可以像这样重写 __getattr__()
方法:
class ModelA(models.Model):
# your fields
def __getattr__(self, name):
if(name == 'fieldA' and !self.fieldA):
return self.get_previous()
else:
return super(ModelA, self).__getattr__(name)
要保存对象的默认值会稍微复杂一点。我想到的第一个解决方案是 重写 save()
方法(我觉得还有更简单的解决办法)
16
在你的例子中,你需要去掉调用运算符 ()
。
现在这个语句会在第一次读取和解析时立即执行。如果你只写符号名称,Django 类就会得到一个函数指针,它会在真正需要默认值的时候去执行这个函数。
这样例子就变成了:
def get_previous():
return ModelA.objects.all()[0].fieldA
class ModelA(models.Model):
fieldA = models.CharField(default=get_previous)
如果你要对很多字段都这样做,建议你重写 save
函数,这样你只需要从数据库中获取一次之前的对象。