Как добавить два поля формы (одно показанное и одно нет) к полю модели

У меня есть класс модели Spent, который хранит название места, где пользователь потратил деньги, их количество, причину, по которой он потратил деньги, и общую потраченную сумму. На форме в шаблоне общая сумма не отображается, только название, место и сколько было потрачено (нет необходимости показывать общую сумму). Я не могу понять, как обновить общую потраченную сумму. Я бы хотел, чтобы общая потраченная сумма отслеживала, сколько пользователь потратил всего.

modles.py

from django.db import models
from django.contrib.auth.models import User


class Bills(models.Model):
    name = models.CharField(max_length=25)
    amount = models.FloatField()
    due_date = models.DateField()
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.name


class Budget(models.Model):
    income = models.FloatField(default=0.00)
    budget = models.FloatField(default=0.00)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.user.username


class Spent(models.Model):
    name = models.CharField(max_length=25)
    amount = models.FloatField(default=0.00)
    reason = models.TextField(default="")
    total_spent = models.FloatField(default=0.00)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.user.username

forms.py

from django import forms
from .models import Bills, Budget, Spent


class DateInput(forms.DateInput):
    input_type = 'date'


class AddBillForm(forms.ModelForm):
    class Meta:
        model = Bills
        fields = ['name', 'amount', 'due_date']

        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter bill name'}),
            'amount': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter the bill amount ex: 250.00'}),
            'due_date': DateInput(attrs={'class': 'form-control'}),
        }


class UpdateBillForm(forms.ModelForm):
    class Meta:
        model = Bills
        fields = ['name', 'amount', 'due_date']

        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control'}),
            'amount': forms.NumberInput(attrs={'class': 'form-control'}),
            'due_date': DateInput(attrs={'class': 'form-control'})
        }


class AddBudgetForm(forms.ModelForm):
    class Meta:
        model = Budget
        fields = ['income', 'budget']

        widgets = {
            'income': forms.NumberInput(attrs={'class': 'form-control'}),
            'budget': forms.NumberInput(attrs={'class': 'form-control'})
        }


class UpdateBudgetForm(forms.ModelForm):
    class Meta:
        model = Budget
        fields = ['income', 'budget']

        widgets = {
            'income': forms.NumberInput(attrs={'class': 'form-control'}),
            'budget': forms.NumberInput(attrs={'class': 'form-control'})
        }


class AddSpentForm(forms.ModelForm):

    class Meta:
        model = Spent
        fields = ['name', 'amount', 'reason']

        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control'}),
            'amount': forms.NumberInput(attrs={'class': 'form-control'}),
            'reason': forms.Textarea(attrs={'class': 'form-control'})
        }

views.py

from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from .models import Bills, Budget, Spent
from .forms import AddBillForm, UpdateBillForm, AddBudgetForm, UpdateBudgetForm, AddSpentForm


class AddBillView(CreateView):
    model = Bills
    template_name = 'budget/add-bill.html'
    form_class = AddBillForm
    success_url = reverse_lazy('profile')

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super().form_valid(form)


class UpdateBillView(UpdateView):
    model = Bills
    template_name = 'budget/update-bill.html'
    form_class = UpdateBillForm
    success_url = reverse_lazy('profile')

    def form_valid(self, form):
        form.instance.user = self.request.user
        form.instance.total_spent = self.amount + self.total_spent
        return super().form_valid(form)


class DeleteBillView(DeleteView):
    model = Bills
    template_name = "budget/delete-bill.html"
    success_url = reverse_lazy('profile')


class CreateBudgetView(CreateView):
    model = Budget
    template_name = "budget/budget.html"
    form_class = AddBudgetForm
    success_url = reverse_lazy('profile')

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super().form_valid(form)


class UpdateBudgetView(UpdateView):
    model = Budget
    template_name = "budget/update-budget.html"
    form_class = UpdateBudgetForm
    success_url = reverse_lazy('profile')

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super().form_valid(form)


class AddSpentView(CreateView):
    model = Spent
    template_name = 'budget/add-spent.html'
    form_class = AddSpentForm
    success_url = reverse_lazy('profile')

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super().form_valid(form)

Сейчас самое время переопределить метод .save() в forms.py
. Я не был уверен, как именно связаны ваши модели... Но вот в общих чертах

class AddBillForm(forms.ModelForm):
    class Meta:
        model = Bills
        fields = ['name', 'amount', 'due_date']

        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter bill name'}),
            'amount': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter the bill amount ex: 250.00'}),
            'due_date': DateInput(attrs={'class': 'form-control'}),
        }

    def save(self):
        obj = super(AddBillForm, self).save(commit=False)
        if commit:
            obj.save()

            # Get the Spent Obj
            spentObj = Spent.objects.get(name=self.cleaned_data.get('name'))
            # Update it
            spentObj.total_spent += self.cleaned_data.get('amount')
            spentObj.save()
            # ^ you could also update this with F('') statements!


class UpdateBillForm(forms.ModelForm):
    class Meta:
        model = Bills
        fields = ['name', 'amount', 'due_date']

        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control'}),
            'amount': forms.NumberInput(attrs={'class': 'form-control'}),
            'due_date': DateInput(attrs={'class': 'form-control'})
        }

    def save(self):
        oldamt = obj.amount

        obj = super(AddBillForm, self).save(commit=False)

        if commit:
            obj.save()

            # I hope oldamt is still correct after the save
            the_change = self.cleaned_data.get('amount')-oldamt

            # Get the Spent Obj
            spentObj = Spent.objects.get(name=self.cleaned_data.get('name'))
            # Update it
            spentObj.total_spent += the_change
            spentObj.save()
Вернуться на верх