Django模型继承层次结构中字段的基于类的默认值

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

在下面的方案中,如何实现基于类的默认值?我的意思是,我希望继承类以不同的方式设置“number”的默认值:

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