更好的django模型设计

icn*_*icn 3 python django django-models

这是我的情况:

我有一个django模型:

class Invoice(models.Model):
    invoiceid = models.CharField(max_length=20)
    totalamount = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    downpayment = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    subtotal = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    tax = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    amountdue = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    payment = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    originaldate = models.DateTimeField()
    changedate = models.DateTimeField()
    version = models.IntegerField(default=1)
    operator = models.CharField(max_length=20)
Run Code Online (Sandbox Code Playgroud)

我有一个非常相同的模型来保存所有更新的历史记录.这个InvoiceHistory基本上只保留所有更新.

class InvoiceHistory(models.Model):
    invoiceid = models.CharField(max_length=20)
    totalamount = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    downpayment = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    subtotal = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    tax = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    amountdue = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    payment = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    originaldate = models.DateTimeField()
    changedate = models.DateTimeField()
    version = models.IntegerField()
    operator = models.CharField(max_length=20)
Run Code Online (Sandbox Code Playgroud)

我知道这种设计效率不高且容易出错.每当业务逻辑发生变化时,我都需要更新两个模型,很容易忘记更改另一个模型.这个问题有更好的django模型设计吗?

谢谢

exf*_*zik 9

您可以创建一个抽象基类,并让两个模型继承它:

class InvoiceAbstract(models.Model):
    invoiceid = models.CharField(max_length=20)
    totalamount = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    downpayment = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    subtotal = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    tax = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    amountdue = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    payment = models.DecimalField(max_digits=15,decimal_places=2,default=0)
    originaldate = models.DateTimeField()
    changedate = models.DateTimeField()
    version = models.IntegerField(default=1)
    operator = models.CharField(max_length=20)
    class Meta:
        abstract = True

class Invoice(InvoiceAbstract):
    pass
class InvoiceHistory(InvoiceAbstract):
    pass
Run Code Online (Sandbox Code Playgroud)

https://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-classes