Question: I'm creating a table with a formset from a queryset of existing objects. Few fields in the table should change, and other fields should be displayed, but not changed. For displaying non-editable fields, I use the widget with 'disabled' in the form. GET request does everything right. But the POST request does not save changes to the resolved fields, because unresolved fields are required and have disabled and blocks the sending of existing values. I tried to use jQuery from the example, but it doesn't work. Moreover, I do not understand how I can refer to different ids in the formset. Models: class Order(models.Model): car = models.ForeignKey( Car, blank=True, null=True, on_delete=models.PROTECT, related_name='car_orders', ) department = models.ForeignKey( Department, blank=False, null=False, on_delete=models.PROTECT, related_name='dep_orders', ) ...  View def orders_list(request, year, month, day): orders = Order.objects.filter( order_date__year=year, order_date__month=month, order_date__day=day ) if request.method == 'POST': formset = OrderCloseFormSet( request.POST or None, queryset=orders, prefix='order' ) if formset.is_valid(): formset.save(commit=False) for form in formset: form.save() formset = OrderCloseFormSet(queryset=orders, prefix='order') context = {'orders': orders, 'formset': formset} return render(request, 'orders/orders_list.html', context)  Form class OrderCloseForm(forms.ModelForm): class Meta: model = Order fields = ( 'type_car', 'department', ... ) widgets = { 'car': forms.Select(attrs={'style': 'width: 100%'}), 'department': forms.Select(attrs={'disabled': 'True', 'style': 'width: 100%'}), ... }  Template <form method="post" action="{% url 'orders:orders_list' year month day %}"> {% csrf_token %} {{ formset.management_form }} {{ formset.non_form_errors.as_ul }} <table class="table table-order" id="order-formset"> {% for form in formset %} {% if forloop.first %} <thead> <tr> {% for field in form.visible_fields %} <th>{{ field.label|capfirst }}</th> {% endfor %} </tr> </thead> {% endif %} <tbody> <tr> {% for field in form %} <td> {% if field == car %} {% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %} {% endif %} {% if field == form.route_movement %} <a href="{% url 'orders:order_detail' form.id.value %}"> {{ field|addclass:'input-box input-select' }} </a> {% else %} {{ field|addclass:'input-box input-select' }} {% endif %} </td> {% endfor %} </tr> </tbody> {% endfor %} </table> ... </form> <script> $('id_order-0-department').submit(function(e) { $(':disabled').each(function(e) { $(this).removeAttr('disabled'); }) }); </script>  In response, get the form id in the formset with next id: <select name="order-0-department" disabled="True" id="id_order-0-department"></select>  So how do I make a table with editable fields, but keeps the data in unchanged fields.

Answer: Setting disabled will only render the field non-editable, so people can still forge a POST request that would alter the field. You should set the field to .disabled = True, this will not only skip the fields, but also prevent people from forging a POST request that somehow would change these fields, like: class OrderCloseForm(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['department'].disabled = True class Meta: model = Order fields = ( 'type_car', 'department', # … ) widgets = { 'car': forms.Select(attrs={'style': 'width: 100%'}), 'department': forms.Select(attrs={'style': 'width: 100%'}), # … } The view is actually a lot simpler than currently done: you can save the FormSet directly: def orders_list(request, year, month, day): orders = Order.objects.filter( order_date__year=year, order_date__month=month, order_date__day=day ) if request.method == 'POST': formset = OrderCloseFormSet( request.POST, request.FILES, queryset=orders, prefix='order' ) if formset.is_valid(): formset.save() # commit=True return redirect('name-of-some-view') else: formset = OrderCloseFormSet(queryset=orders, prefix='order') context = {'orders': orders, 'formset': formset} return render(request, 'orders/orders_list.html', context)   Note: In case of a successful POST request, you should make a redirect [Django-doc] to implement the Post/Redirect/Get pattern [wiki]. This avoids that you make the same POST request when the user refreshes the browser.