Django: Updateview inlineformset error - (Hidden field id) This field is required
Asked Answered
L

2

9

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> 
Leija answered 4/10, 2018 at 12:30 Comment(0)
G
9

Make sure to loop over hidden fields if you are manually laying out a formset in a template.

{% for hidden in form.hidden_fields %}
    {{ hidden }}
{% endfor %}

Reference: https://docs.djangoproject.com/es/2.1/topics/forms/#looping-over-hidden-and-visible-fields

Godding answered 25/2, 2019 at 18:21 Comment(2)
how just looping over hidden fields resolve the error?Foredo
This helped to resolve my issue, thanks !Direct
B
1

for django 4.2 just add {{ formset.management_form }}

for example

 {{ formset.management_form }}
    {% for form in formset %}
        {{ form.as_table }}
    {% endfor %}
Breechloader answered 20/10, 2023 at 0:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.