Как добавить два поля формы (одно показанное и одно нет) к полю модели
У меня есть класс модели 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()