SGH
SGH

Reputation: 7

Is overriding the Django model's save function okay in this scenario?

So, I have a model, whose save function has some side effects like this:

from django.db import models

class Customer(models.Model):
    customer_name = models.CharField(max_length=255)
    customer_email = models.EmailField()
    customer_phone = models.CharField(max_length=20)
    customer_address = models.CharField(max_length=255)

class Product(models.Model):
    product_name = models.CharField(max_length=255)
    product_description = models.TextField()
    product_price = models.DecimalField(max_digits=10, decimal_places=2)

class Order(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
    order_date = models.DateField()
    order_total = models.DecimalField(max_digits=10, decimal_places=2)

class Order_Item(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.IntegerField()
    item_price = models.DecimalField(max_digits=10, decimal_places=2)

class User(models.Model):
    username = models.CharField(max_length=255)
    email = models.EmailField()
    password = models.CharField(max_length=255)

class OrderFolder(models.Model):
    REASON_ARCHIVED = 'ARCHIVED'
    REASON_REVIEW = 'REVIEW'
    REASON_CHOICES = [
        (REASON_ARCHIVED, 'Archived'),
        (REASON_REVIEW, 'Review'),
    ]
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    reason = models.CharField(max_length=10, choices=REASON_CHOICES)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

class Payment(models.Model):
    payment_date = models.DateField()
    payment_amount = models.DecimalField(max_digits=10, decimal_places=2)
    payment_method = models.CharField(max_length=50)
    order = models.ForeignKey('Order', on_delete=models.CASCADE)

    def save(self, *args, **kwargs):
      super(Payment, self).save(*args, **kwargs)

      # If order is paid and order is not in review, move it to the ARCHIVED folder
      if self.order.order_total == self.payment_amount:
        of = OrderFolder.objects.get(pk = self.order.id)
        if of.reason != 'Review':
          of.reason = 'ARCHIVED'
          of.save()

In the above code, I override the Payment's save method to have a side effect in another table. Django allows overriding save method, but is this approach acceptable considering:

  1. Potentially breaking the Single responsibility principle in the SOLID design
  2. Potentially introducing tight coupling.
  3. Introducing business logic in the model's save

Upvotes: 1

Views: 41

Answers (0)

Related Questions