FrostyDuke
FrostyDuke

Reputation: 31

Updating cleaned_data based on form input?

I am trying to adjust the cleaned_data that I get from the modelform to save certain values to the model based on the users input. These inputs can vary greatly, please see the model below along with the forms and views.

Should I call the model methods into the model form or should I do all the calculations in the modelForm itself. The figures can change depending on the contract selected and the start date selected as it will count the number of days and base it on this price for the contract, however if it is a half day then it will just divide the number by 2.

I am still new to Django but trying to figure out where all this information should be put, I am certainly clueless on this and trying to learn Django myself through real lifelike applications instead so appreciate your help.

Model

class AdminData(models.Model):
    year1 = models.IntegerField()
    year3 = models.IntegerField()
    year1_fortnight = models.IntegerField()
    year3_fortnight = models.IntegerField()

    @property
    def fortnight_dayrate_year1(self):
        return self.year1_fortnight / weeksinyear / 5

    @property
    def fortnight_dayrate_year3(self):
        return self.year3_fortnight / weeksinyear / 5

    @property
    def day_rate_year1(self):
        return self.year1 / weeksinyear / 5

    @property
    def day_rate_year3(self):
        return self.year3 / weeksinyear / 5


class Price(models.Model):
        year_choice = Choices('1-Year Weekly', '3-Year Weekly','1-Year Fortnightly', '3-Year Fortnightly')
        day_choice = Choices('Full Day', 'Half Day')
        name = models.CharField(max_length=100)
        contract = StatusField(choices_name='year_choice')
        time_daily = StatusField(choices_name='day_choice')
        start_date = models.DateField(default=datetime.now)
        end_date = models.DateField(default=datetime(2021,3,31))
        weeksinyear = 52
        hours = 6.5
        epoch_year = date.today().year
        year_start = date(epoch_year, 1, 4)
        year_end = date(epoch_year, 3, 31)

        @property
        def day_count(self):
            return year_end - self.start_date


     #   @property
      #  def price_year1_weekly(self):
      #      if self.contract == self.year_choice[0]
        #        return AdminData.year1 * self.day_count


        def __str__(self):
            return self.name

Forms.py

class PriceForm(forms.ModelForm):
    class Meta:
            model = Price
            fields = ['name', 'contract','time_daily','start_date']

Views.py

    def price_detail(request):

    if request.method == 'POST':
        form = PriceForm(request.POST)

        if form.is_valid():
           price_instance = form.cleaned_data
           form.save()
        return render(request,'confirmation.html',{'form_data': price_instance})
    else:
        form = PriceForm()


    return render(request, 'main.html', {'form': form})

Upvotes: 0

Views: 107

Answers (1)

Michael Lindsay
Michael Lindsay

Reputation: 1355

For at the time of transaction calculations, the views.py is a good place for this, ie. a purchase, where the price is agreed upon at that moment and will never change.

If the business logic requires that the data updates the transaction, then the model is better.

views.py

def price_detail(request):
    form = PriceForm(request.POST or None)

    if form.is_valid():
        price_instance = form.save() // this returns a saved instance
        ... do calculations here ...
        price_instance.calculated_field = 1 + 1 // example calculations
        price_instance.confirmed = False // consider adding a confirmed boolean, to not allow users to alter the data in the next step.
        price_instance.save()

        return render(request, 'confirmation.html', {'price_instance': price_instance})
    else:
        return render(request, 'main.html', {'form': form})

An example of doing the calculations every time the model is saved by overriding the model's save() method.

models.py

class Price(models.Model):
    year_choice = Choices('1-Year Weekly', '3-Year Weekly','1-Year Fortnightly', '3-Year Fortnightly')
    day_choice = Choices('Full Day', 'Half Day')
    name = models.CharField(max_length=100)
    contract = StatusField(choices_name='year_choice')
    time_daily = StatusField(choices_name='day_choice')
    start_date = models.DateField(default=datetime.now)
    end_date = models.DateField(default=datetime(2021,3,31))
    weeksinyear = 52
    hours = 6.5
    epoch_year = date.today().year
    year_start = date(epoch_year, 1, 4)
    year_end = date(epoch_year, 3, 31)

    @property
    def day_count(self):
        return year_end - self.start_date

    def save(self, *args, **kwargs):
        ... do calculations here ...
        self.calculated_field = 1 + 1 // calculations
        super().save(*args, **kwargs)


    def __str__(self):
        return self.name

Upvotes: 1

Related Questions