how do i icrement a filed on a model name:''order count' when an another model object is created in django

Viewed 34

I have two models Customer and Order and I want to make 3 fields that are updating when an Order object is created. the fields are Order_Count:--, First_Order:order_date, Last_Order: order_date

how do I do this?

Customer model:

class Customer(models.Model):
GENDER_CHOICES = (
    ('MALE', 'male'),
    ('FEMALE', 'female'),
    ('OTHER', 'other')
)
SOURCES = (
    ('android', 'Android'),
    ('ios', 'IOS')
)
customer = models.ForeignKey(User, related_name='customer', on_delete=models.CASCADE)
image = models.ImageField(upload_to='customer_images/', null=True, blank=True)
social_image_url = models.TextField(null=True, blank=True)
dob = models.DateField(null=True, blank=True)
gender = models.CharField(max_length=10, choices=GENDER_CHOICES, null=True, blank=True)
lati = models.CharField(max_length=100, null=True, blank=True)
long = models.CharField(max_length=100, null=True, blank=True)
fb_id = models.CharField(max_length=50, null=True, blank=True)
google_id = models.CharField(max_length=50, null=True, blank=True)
gapple_sub = models.CharField(max_length=50, null=True, blank=True)
notifications = models.BooleanField(default=True)
payment_token = models.CharField(max_length=200, null=True, blank=True)
source = models.CharField(max_length=10, choices=SOURCES, null=True, blank=True)
a_v = models.CharField(max_length=20, null=True, blank=True)

def __str__(self):
    # return "%s" % self.customer.get_full_name()
    return f'{self.id} - {self.customer.get_full_name()}'

and Order model:


    class Order(models.Model):
    STATUS_CHOICES = (
        (0, 'cancelled'),
        (1, 'new'),
        (2, 'accepted'),
        (3, 'waiting_for_driver'),
        (4, 'assigned_to_driver'),
        (5, 'waiting_to_pick_from_customer'),
        (6, 'picked_from_customer'),
        (7, 'reached_store_waiting'),
        (8, 'reached_store'),
        (9, 'processing'),
        (10, 'ready_to_pickup'),
        (11, 'waiting_for_driver_store'),
        (12, 'assigned_to_driver_store'),
        (13, 'picked_up_from_store_waiting'),
        (14, 'picked_up_from_store'),
        (15, 'delivered'),
        )
    
2 Answers

I would suggest to overwrite the save() method of your Order model to calculate and set those values at order creation. Example:

class Order(models.Model):
    ...
    def save(self, *args, **kwargs):
        if self._state.adding:  # order is created       
            self.order_count = my_count # something calculated
        super().save(*args, **kwargs)

For date fields you may also want to checkout the auto_now_add feature. With that the order date will automatically set when created.

See also:

In addition to what Erik has suggested you can also use signals ( specifically post_save in this case ) to achieve this. Using that you can avoid cluttering up your models and handle dependent actions separately and in a cleaner way.

@receiver(post_save, sender=Order)
def update_order_count(sender, instance, **kwargs):
   <logic_to_update_fields_in_customer_model>

On every Order save, this listener will be called and based on whatever logic you provide you can perform operations like update another model, creating audit entries and pretty much anything you want.

Refer to Django signals: https://docs.djangoproject.com/en/4.0/topics/signals/

Related