Django:字段自身模型实例的默认值

时间:2010-08-26 09:36:58

标签: django default field

如何为从模型的现有对象中获取的字段设置默认值?

我尝试了这些并且没有用:

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)不起作用 - 看起来类的'本能不能引用实例(即自我)。 我可以想象为什么2)不起作用 - 显然没有对ModelA的引用,直到解释器将通过全班。

那我该怎么做呢?

3 个答案:

答案 0 :(得分:16)

在您的示例中,您需要删除调用运算符()

目前,语句在第一个读取解析周期立即执行。通过指定符号名称,Django类接收一个函数指针,它将在实际需要默认值时执行。

示例变为:

def get_previous():
    return ModelA.objects.all()[0].fieldA

class ModelA(models.Model):
    fieldA = models.CharField(default=get_previous)

如果要对很多字段执行此操作,请考虑覆盖save函数,这样您只需要从数据库中获取前一个对象一次。

答案 1 :(得分: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)

从对象保存默认值会有点困难。我想到的第一个解决方案override save() method(我相信有更简单的解决方案)

答案 2 :(得分:3)

选项1:Use model forms。这些是基于模型的表单,您可以使用特定实例中的值轻松填充其值。如果您希望将默认值显示为表单中的用户,则此选项很有用。

选项2:Override the model's save method,并在那里对检查进行编码 - 如果fieldA为None,则在其中加入一些值。如果您希望默认值在数据层工作,并且不仅仅是表单默认值(也适用于您以其他方式创建的实例),则此选项更好。