Django模型字段默认基于在同一模型中的另一个字段

我有一个模型,我想包含一个主题名称和他们的首字母缩写。 (这些数据有点匿名,并用首字母进行跟踪。)

现在,我写了

class Subject(models.Model): name = models.CharField("Name", max_length=30) def subject_initials(self): return ''.join(map(lambda x: '' if len(x)==0 else x[0], self.name.split(' '))) # Next line is what I want to do (or something equivalent), but doesn't work with # NameError: name 'self' is not defined subject_init = models.CharField("Subject Initials", max_length=5, default=self.subject_initials) 

如最后一行所示,我希望能够将首字母实际上作为字段(独立于名称)存储在数据库中,但是该名称是使用基于名称字段的默认值初始化的。 但是,由于Django模型似乎没有“自我”,所以我遇到了问题。

如果我subject_init = models.CharField("Subject initials", max_length=2, default=subject_initials)一行更改为subject_init = models.CharField("Subject initials", max_length=2, default=subject_initials) ,我可以执行syncdb,但不能创build新的主题。

这是可能的Django中,有一个可调用函数根据另一个字段的值给一个字段的默认值?

(奇怪的是,我想单独分开商店名称的原因很罕见,奇怪的姓氏可能跟我跟踪的姓氏不一样,例如,其他人决定把主语1命名为“John O'Mallory”首字母缩写“JM”而不是“JO”,并且想要修改它作为pipe理员的编辑。)

模型肯定有一个“自我”! 只是你试图将一个模型类的属性定义为依赖于一个模型实例; 这是不可能的,因为在定义类及其属性之前,实例没有(也不能)存在。

要获得所需的效果,请覆盖模型类的save()方法。 对所需的实例进行任何更改,然后调用超类的方法来进行实际的保存。 这是一个简单的例子。

 def save(self, *args, **kwargs): if not self.subject_init: self.subject_init = self.subject_initials() super(Subject, self).save(*args, **kwargs) 

这在覆盖模型方法在文档中介绍。

我不知道是否有更好的方法来做这件事,但是您可以使用 pre_save信号 的信号处理程序 :

 from django.db.models.signals import pre_save def default_subject(sender, instance, using): if not instance.subject_init: instance.subject_init = instance.subject_initials() pre_save.connect(default_subject, sender=Subject)