Hi,
I’m trying to evaluate using Inline formsets for a project, but at the moment I’m struggling to save data from the updated formset into the database.
In principle, I used the same logic to create a formset, as it seems to be the same
Form
class LeadEntryForm(forms.ModelForm):
class Meta:
model = LeadEntry
fields = ('lead_id','date','revenue','probability')
widgets = {'date': DateInput()}
This view creates the Formset for a given Lead:
@login_required
def data_form_forecast(request):
# gets the project number
lead_id = request.GET.get('project_id')
#Gets the lead associated with the LeadEntry (Child Object)
lead = get_object_or_404(Leads, pk=lead_id)
# Create an inline formset using Leads the parent model and LeadEntry as child
FormSet = inlineformset_factory(Leads, LeadEntry, form=LeadEntryForm, extra=4)
if request.method == "POST":
formset = FormSet(request.POST,instance=lead)
if formset.is_valid():
formset.save()
return redirect('dashboard')
context = {
'formset': FormSet(instance=lead, queryset=LeadEntry.objects.none())
}
return render(request, "account/lead_forecast.html", context)
This is the form to create the formset
<h1> Add Lead to Sales Forecast </h1>
<h3>Enter Payment Details</h3>
<br>
<div class="container-fluid" >
<form method="POST" enctype="multipart/form-data" >
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
<div class="row justify-content-left">
<div class="col-sm-2">
{{ form.date|as_crispy_field }}
</div>
<div class="col-sm-2">
{{ form.revenue|as_crispy_field }}
</div>
<div class="col-sm-1">
{{ form.probability|as_crispy_field }}
</div>
</div>
<hr>
{% endfor %}
<div class="row justify-content-center">
<div class="col-sm">
<button type="submit" class="buttons" > Submit </button>
</div>
</div>
</form>
</div>
This functionality works perfectly fine.
I created the update formset in a similar way, and I do see the data entered in the other form, but the form is not submitting the data.
@login_required
def update_forecast(request):
## gets the project number
lead_id = request.GET.get('project_id')
# Gets the lead queryset
lead = get_object_or_404(Leads,pk=lead_id)
#Create an inline formset using Leads the parent model and LeadEntry the child model
FormSet = inlineformset_factory(Leads,LeadEntry,form=LeadEntryForm,extra=0)
if request.method == "POST":
formset = FormSet(request.POST,instance=lead)
if formset.is_valid():
form.save()
return redirect('dashboard')
context = {
'formset':FormSet(instance=lead)
}
return render(request,"account/leadentry_update.html",context)
HTML view for updating an entry
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block title %}Client Information {% endblock %}
{% block content %}
<h1> Update Forecast </h1>
<h3> Use the form below to update your forecast </h3>
<br>
<div class="container-fluid" >
<form method="POST" enctype="multipart/form-data" >
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
<div class="row justify-content-left">
<div class="col-sm-2">
{{ form.date|as_crispy_field }}
</div>
<div class="col-sm-2">
{{ form.revenue|as_crispy_field }}
</div>
<div class="col-sm-1">
{{ form.probability|as_crispy_field }}
</div>
</div>
<hr>
{% endfor %}
<div class="row justify-content-center">
<div class="col-sm">
<button type="submit" class="buttons" > Submit </button>
</div>
</div>
</form>
</div>
I understand that is better to use a Class-based view, and I’m working towards that route, but I want to understand a function-based view, before jumping into class-based ( Django Class-Based Views and Inline Formset Example (github.com)
When I try to update the lead, there is no error shown, I can see a post request in the terminal:
[07/Dec/2021 10:17:58] “POST /account/update_forecast/?project_id=17 HTTP/1.1” 200 11682
And for example, if one of the fields has a value of 0.2, and I try to change it to 0.4, upon hitting submit the value goes back to 0.2
Thanks
Francisco