Home > OS >  Django model F expression divide by zero error when calculating dynamic running total and average
Django model F expression divide by zero error when calculating dynamic running total and average

Time:03-27

I am using Django 3.2

I am dynamically calculating field values for an item that can be rated.

Here is a snippet of my code:

self.ratings_count = F('ratings_count')   1
self.ratings_total = F('ratings_total')   rating_value
self.ratings_average =  F('ratings_total') / F('ratings_count')  
self.last_rated = timezone.now()
self.save()  # Divide by zero error here (no records exist in Db)

I could trivially get around this by not using F fields (as a kludge - with attendant race conditions). My question is - how do I implement the desired behaviour, whilst using F expressions?

CodePudding user response:

The 1st solution is to save the value of ratings_count & ratings_total before using it in the division operation, like that:

self.ratings_count = F('ratings_count')   1
self.ratings_total = F('ratings_total')   rating_value

self.save(update_fields=['self.ratings_total', 'self.ratings_count']) # try to remove `self` if there are a problme

self.ratings_average =  F('ratings_total') / F('ratings_count')  
self.last_rated = timezone.now()

self.save(update_fields=['ratings_average', 'last_rated']) 

the 2nd solution is:

self.ratings_count = F('ratings_count')   1
self.ratings_total = F('ratings_total')   rating_value

if self.ratings_count == 0 and self.ratings_total == 0:
    self.ratings_average = rating_value
else:
    self.ratings_average = (F('ratings_total')   rating_value) / (F('self.ratings_count') 1)

self.last_rated = timezone.now()

self.save() 

  • Related