How can I run calc_price function immediately after I create a Rental Object? From Build Python Web Apps with Django Djaunty Bike Project

Hi, I was wondering if I could run the calc_price() function automatically after I create a Rental Object, instead of having to call it separately. My code is below. It seems to run without errors.

from django.db import models
import datetime

BASE_PRICE = 25.00
TANDEM_SURCHARGE = 15.00
ELECTRIC_SURCHARGE = 25.00

# Create your models here.
class Bike(models.Model):
  STANDARD = "ST"
  TANDEM = "TA"
  ELECTRIC = "EL"
  BIKE_TYPE_CHOICES = [
    (STANDARD, "Standard"),
    (TANDEM, "Tandem"),
    (ELECTRIC, "Electric")
  ]  
  bike_type = models.CharField(max_length=2,
    choices=BIKE_TYPE_CHOICES,
    default=STANDARD
  )
  color = models.CharField(max_length=10, default="")

  def __str__(self):
    return self.bike_type + " - " + self.color


class Renter(models.Model):
  first_name = models.CharField(max_length=30)
  last_name = models.CharField(max_length=30)
  phone = models.CharField(max_length=15)
  vip_num = models.IntegerField(default=0)

  def __str__(self):
    return f"{self.first_name} {self.last_name} - #{self.phone}"


class Rental(models.Model):
  bike = models.ForeignKey(Bike, on_delete=models.CASCADE)
  renter = models.ForeignKey(Renter, on_delete=models.CASCADE)
  date = models.DateField(default=datetime.date.today)
  price = models.FloatField(default=0.0)

  def calc_price(self):
    curr_price = BASE_PRICE
    if self.bike.bike_type == "TA":
      curr_price += TANDEM_SURCHARGE
    elif self.bike.bike_type == "EL":
      curr_price += ELECTRIC_SURCHARGE
    
    if self.renter.vip_num > 0:
      curr_price = curr_price * 0.80

    self.price = curr_price

  

hi @arrayblaster54767 ,

You can try using Python’s Decorator feature. (Reference link)

After you have instantiate the Rental class, you can call a function within the class to create the variables along with running calc_price function for you.

Hope this helps.

Thanks @estforesta. I ended up using the suggestion from the Django Docs: Model instance reference | Django documentation | Django

I was hoping to have calc_price be called from the constructor function __init__ but the docs recommend not making changes to it. Instead, I modified the Rental class like this:

class Rental(models.Model):
  bike = models.ForeignKey(Bike, on_delete=models.CASCADE)
  renter = models.ForeignKey(Renter, on_delete=models.CASCADE)
  date = models.DateField(default=datetime.date.today)
  price = models.FloatField(default=0.0)

  def calc_price(self):
    curr_price = BASE_PRICE
    if self.bike.bike_type == "TA":
      curr_price += TANDEM_SURCHARGE
    elif self.bike.bike_type == "EL":
      curr_price += ELECTRIC_SURCHARGE
    
    if self.renter.vip_num > 0:
      curr_price = curr_price * 0.80

    self.price = curr_price

  @classmethod
  def create(cls, bike, renter):
    rental = cls(bike=bike, renter=renter)
    rental.calc_price()
    return rental

Now when you’re in the Python shell, instead of creating the rental object like this: Rental(bike, renter), you have to do this: Rental.create(bike, renter).

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.