问题
This is a non-model based Form:
from django import forms
class MeasureForm(forms.Form):
name = forms.CharField(max_length=15)
description = forms.CharField(max_length=100)
datatype = forms.CharField(max_length=20)
uom = forms.Char
Populated from a non-model based view:
def define_measures(request):
measureformset = formset_factory(MeasureForm, extra=2)
if request.method == 'POST': # If the form has been submitted...
formset = measureformset(request.POST ) # A form bound to the POST data
if formset.is_valid(): # All validation rules pass
for form in formset:
print form.changed_data
return HttpResponseRedirect('/viscas/measures') # Redirect after POST
else:
measures = cass.get_all_measures()
list_dict =[]
for measure in measures:
list_dict.append({'name': measure.name, 'description': measure.description, 'datatype': measure.datatype, 'uom': measure.uom})
formset = measureformset(initial=list_dict)
return render(request, 'viscas/measure.html', {
'formset': formset,
})
Being rendered "manually" in a template:
{% extends "base.html" %}
{% block content %}
<body>
<div class="container">
<form action="{% url 'viscas:define_measures' %}" method="post">
{% csrf_token %}
<div>
<table class="table table-hover" name="poi" id="tagTable">
<thead>
<tr>
<th>UOM</th>
<th>Description</th>
<th>Datatype</th>
<th>UOM</th>
</tr>
</thead>
{% for form in formset %}
<tr>
<td>{{ form.name }}</td>
<td>{{ form.description }}</td>
<td>{{ form.datatype }}</td>
<td>{{ form.uom }}</td>
{% if form.errors %}
<tr>
<td>{{ form.errors }}</td>
</tr>{% endif %}
</tr>
{% endfor %}
</table>
{{ formset.management_form }}
</div>
<p></p><input type="submit" value="Submit"/></p>
</form>
</div>
</body>
{% endblock %}
The page displays beautifully, put if I post with no change whatsoever on the web-page, each form is showing all fields changed (except the two extra which come back blank).
from this code:
if request.method == 'POST': # If the form has been submitted...
formset = measureformset(request.POST ) # A form bound to the POST data
if formset.is_valid(): # All validation rules pass
for form in formset:
print form.changed_data
I get this output:
['name', 'description', 'datatype', 'uom']
['name', 'description', 'datatype', 'uom']
['name', 'description', 'datatype', 'uom']
['name', 'description', 'datatype', 'uom']
['name', 'description', 'datatype', 'uom']
['name', 'description', 'datatype', 'uom']
['name', 'description', 'datatype', 'uom']
['name', 'description', 'datatype', 'uom']
['name', 'description', 'datatype', 'uom']
['name', 'description', 'datatype', 'uom']
[]
[]
回答1:
I think your solution is rather simple. Just add {{ formset.management_form }}
above {% for form in formset %}
in your template. It's required to set up any formset in a template.
For more detail see the Django formset page.
来源:https://stackoverflow.com/questions/21174686/in-a-django-formset-being-returned-in-a-post-all-forms-are-showing-all-fields-c