Django中的默认模型字段属性

0 投票
1 回答
1268 浏览
提问于 2025-04-16 09:52

我有一个Django模型:

    @staticmethod
    def getdefault():
        print "getdefault called"
        return cPickle.dumps(set())

    _applies_to = models.TextField(db_index=True, default=getdefault)

出于某种原因,getdefault() 从来没有被调用,即使我在创建这个模型的实例并将它们保存到数据库时。这似乎和Django的文档相矛盾:

Field.default

字段的默认值。这个值可以是一个具体的值,也可以是一个可调用的对象。如果是可调用的,每次创建新对象时都会被调用。

我是不是做错了什么?

更新

最开始我是这样写的,但后来为了调试我换成了上面的版本:

_applies_to = models.TextField(db_index=True, default=cPickle.dumps(set()))

我不太确定为什么那样不行。

更新 2:我仍然在这方面遇到困难。这里是我的模型:

class Threshold(models.Model):
    # ...
    _applies_to = models.TextField(db_index=True, default=lambda: cPickle.dumps(set()))

还有一个测试:

def setUp(self):
    self.threshold = Threshold() 

    self.threshold.save()

def test_default_applies_to(self):
    self.assertEqual(self.threshold._applies_to, cPickle.dumps(set()))  

这个测试失败了。我不太明白为什么。

FAIL: test_default_applies_to (apps.threshold.tests.ThresholdTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tests.py", line 27, in test_default_applies_to
    self.assertEqual(self.threshold._applies_to, cPickle.dumps(set()))
AssertionError: 'N.' != 'c__builtin__\nset\np1\n((ltRp2\n.'

这可能是为什么呢?也许我不太理解default应该怎么工作。

1 个回答

1

去掉staticmethod这个装饰器,它就能正常工作了:

def getdefault():
    print "getdefault called"
    return cPickle.dumps(set())

_applies_to = models.TextField(db_index=True, default=getdefault)

补充:根据你的更新,我觉得在这种情况下,最简单的方法就是直接这样做:

models.TextField(db_index=True, default=lambda: cPickle.dumps(set()) 

至于你第一个例子为什么不工作的原因,是因为cPickle.dumps(set())并不是一个可以调用的东西。你在定义模型的时候,实际上是在执行cPickle.dumps(set())

希望这能帮到你 :)

撰写回答