2011-12-30 93 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