I am trying to edit an updateview in django that has an inlineformset. Below are the model.py, forms.py, views.py, and the template files. The form is not saving, so I placed a print(actor_form) in the post method in the views.py to see what was happening. I got the following html code:
<input type="hidden" name="actor-TOTAL_FORMS" value="1" id="id_actor-TOTAL_FORMS" /><input type="hidden" name="actor-INITIAL_FORMS" value="1" id="id_actor-INITIAL_FORMS" /><input type="hidden" name="actor-MIN_NUM_FORMS" value="0" id="id_actor-MIN_NUM_FORMS" /><input type="hidden" name="actor-MAX_NUM_FORMS" value="1000" id="id_actor-MAX_NUM_FORMS" />
<tr><td colspan="2"><ul class="errorlist nonfield"><li>(Hidden field id) This field is required.</li></ul></td></tr>
<tr><th><label for="id_actor-0-actorName">ActorName:</label></th><td><input type="text" name="actor-0-actorName" value="www" maxlength="50" id="id_actor-0-actorName" /></td></tr>
<tr><th><label for="id_actor-0-DELETE">Delete:</label></th><td><label for="id_actor-0-DELETE" class="checkbox-inline"><input type="checkbox" name="actor-0-DELETE" id="id_actor-0-DELETE" />
</label><input type="hidden" name="actor-0-id" id="id_actor-0-id" /><input type="hidden" name="actor-0-useCase" id="id_actor-0-useCase" /></td></tr>
In the second line above, you can see - (Hidden field id) This field is required.
I believe this is cause the inline to not save, but I do not know how to fix it.
Here is the models.py
class Profile(models.Model):
profileName = models.CharField(max_length=50)
profileBoundary = models.CharField(max_length=3, choices = BOUNDARY_CHOICES)
class Actor(models.Model):
profile= models.ForeignKey(UseCaseProfile, on_delete=models.CASCADE , null=True, blank=True)
actorName=models.CharField(max_length=50)
here is the forms.py
class ProfileForm(ModelForm):
class Meta:
model=Profile
exclude = ('project',)
class ActorForm(ModelForm):
class Meta:
model=Actor
fields ='__all__'
views.py
class ProUpdateView(UpdateView):
template_name = 'Update.html'
model = Profile
form_class = ProfileForm
def get_success_url(self):
self.success_url = reverse_lazy ('useCaseExtract:UseCaseList', kwargs={'project': self.kwargs['project']})
return self.success_url
def get_context_data(self, **kwargs):
context = super(ProUpdateView, self).get_context_data(**kwargs)
if self.request.POST:
context['actor_form'] = ActorFormSet(self.request.POST, instance=self.object, prefix='actor')
else:
context['actor_form'] = ActorFormSet(instance=self.object,prefix='actor')
return context
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form_class = self.get_form_class()
form = self.get_form(form_class)
actor_form = ActorFormSet(self.request.POST,prefix='actor')
print(actor_form)
if (form.is_valid() and actor_form.is_valid()):
return self.form_valid(form, actor_form)
else:
return self.form_invalid(form, actor_form)
def form_valid(self, form, actor_form):
self.object = form.save()
actor_form.instance = self.object
actor_form.save()
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form, actor_form):
return self.render_to_response( self.get_context_data(form=form, actor_form=actor_form))
template
<form method="POST" enctype="multipart/form-data" style="margin-left: 40px; margin-right: 40px">
{% for hidden_field in form.hidden_fields %}
{% endfor %}
{% csrf_token %}
{{ form.management_form }}
{{ form.non_form_errors }}
<h4>Use Case Profile:</h4>
{% bootstrap_form form %}
<h4>Supported Role(s):</h4>
<div >
{% for hidden_field in actor_form.hidden_fields %}
{% endfor %}
{{ actor_form.management_form }}
{{ actor_form.non_form_errors }}
{% for aform in actor_form %}
<div >
{{ aform.actorName.errors }}
{% bootstrap_field aform.actorName %}
</div>
{% endfor %}
</div>
</div>
<hr style = "border: 0; border-top: 1px solid #999; margin: 1em 0;">
<a style="margin-left: 350px;" class="text-danger" href="{% url 'useCaseExtract:UseCaseList' view.kwargs.project %}"> {% bootstrap_icon "remove" %} Cancel</a>
<input class="btn btn-success" type="submit" value="Update" />
</form>
</div>
<!-- main_container ends here -->
</div>