Django模型继承层次结构中字段的基于类的默认值
在下面的方案中,如何实现基于类的默认值?我的意思是,我希望继承类以不同的方式设置“number”的默认值:Django模型继承层次结构中字段的基于类的默认值,django,dynamic,model,default,field,Django,Dynamic,Model,Default,Field,在下面的方案中,如何实现基于类的默认值?我的意思是,我希望继承类以不同的方式设置“number”的默认值: class OrderDocumentBase(PdfPrintable): number = models.PositiveIntegerField(default=self.create_number()) @classmethod def create_number(cls): raise NotImplementedError class
class OrderDocumentBase(PdfPrintable):
number = models.PositiveIntegerField(default=self.create_number())
@classmethod
def create_number(cls):
raise NotImplementedError
class Invoice(OrderDocumentBase):
@classmethod
def create_number(cls):
return 1
class CreditAdvice(OrderDocumentBase):
@classmethod
def create_number(cls):
return 2
我已经看过了,但它没有解决同样的问题。我认为唯一可行的方法是重载OrderDocumentBase的\uuuu init\uuuu
方法,如下所示:
def __init__(self, *args, **kwargs):
"""
Overload __init__ to enable dynamic set of default to number
"""
super(OrderDocumentBase, self).__init__(*args, **kwargs)
number_field = filter(lambda x: x.name == 'number', self._meta.fields)[0]
number = self.__class__.create_number()
number_field.default = number
这是可行的,但只是部分可行,而且表现得相当顽强。在管理界面中,我可以看到只有在第二次或之后的页面刷新后才设置默认值。第一次尝试时,设置了None
:(
第二种可能是在每个类中重新定义数字字段,但这似乎不太好。还有其他方法吗
有人能帮忙吗?这里有几个问题。首先,
self.method
不起作用。在类主体的上下文中没有self
,您在这里声明PositiveIntegerField
第二,传递一个可调用函数将不起作用,因为可调用函数在编译时被绑定,并且在运行时不会更改
class OrderDocumentBase(PdfPrintable):
create_number = lambda: return 0
number = models.PositiveIntegerField(default=create_number)
class Invoice(OrderDocumentBase):
create_number = lambda: return 1
所有Invoice
实例仍将获得0
作为默认值
解决这个问题的一种方法是重写save()
方法。您可以检查编号是否未提供,并在保存之前将其设置为默认值
class OrderDocumentBase(PdfPrintable):
number = models.PositiveIntegerField()
def save(self, *args, **kwargs):
if not self.number:
self.number = self.DEFAULT
super(OrderDocumentBase, self).save(*args, **kwargs)
class Invoice(OrderDocumentBase):
DEFAULT = 2
class CreditAdvice(OrderDocumentBase):
DEFAULT = 3
我对上述内容进行了测试,只是做了一个小改动(由于我没有PdfPrintable,所以做了OrderDocumentBase
摘要)通过default=,它确实感觉更好,但是您在那里使用的任何东西都无法访问您的类或特定模型。要让它在像admin这样的地方正确显示,您可以在init()中设置它,而不是在save()中设置它
这不会给您一个语法错误number=models.PositiveIntegerField(默认值=self.create\u number())
?在这种情况下没有self
。是的,它有-我只是想展示一些类似于我需要实现的解决方案的东西。很抱歉,我误导了剪报。我知道我使用的剪报不起作用,我只是想展示我希望它能起作用的方式:)您的解决方案的问题是,在创建新对象时,默认值在Django admin中不可见,这是我需要的必要功能。似乎唯一的解决方案是在每个子模型中重新定义。这真的对管理有帮助吗?我的管理面板显示---作为此解决方案的初始值。
class OrderDocumentBase(PdfPrintable):
number = models.PositiveIntegerField()
def __init__(self, *args, **kwargs):
super(OrderDocumentBase, self).__init__(*args, **kwargs)
if not self.pk and not self.number:
self.number = self.DEFAULT_NUMBER
class Invoice(OrderDocumentBase):
DEFAULT_NUMBER = 2
class CreditAdvice(OrderDocumentBase):
DEFAULT_NUMBER = 3