2011-12-30 59 views
3

这里是我的情况:更好的Django模型设计

我有一个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) 

,我有一个几乎相同的模式,让所有的更新历程。这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) 

我知道这样的设计是不是很有效,而且容易出错。每当业务逻辑发生变化时,我都需要更新两个模型,并且很容易忘记更改另一个模型。是否有更好的Django模型设计来解决这个问题?

感谢

+2

这取决于你需要这方面的数据做什么。我倾向于有一个文本字段,可以简单地存储换行符分隔的事件:“用户X将字段Y从A更改为B - 时间戳”。如果你需要完整版本控制,那么有一个伟大的项目:https://github.com/etianen/django-reversion – 2011-12-30 06:47:27

+1

你正在重新发明轮子。我建议你按照Yuji的建议。 – jpic 2011-12-30 09:28:15

回答

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 

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