Reputation: 17876
Here is my situation:
I have a django model:
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)
and I have a pretty much identical model to keep all updated history. This InvoiceHistory basically just keeps all updates.
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)
I know this design is not very efficient and error-prone . Whenever business logic changes I need to update both models and it is easy to forget to change the other one. Is there a better django model design for this problem?
Thanks
Upvotes: 3
Views: 1977
Reputation: 5701
You could create an abstract base class and have both models inherit from it:
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
Upvotes: 9