So, I'm using Django's Model Formset to produce sets of forms for different data. It is working great, but I want to add a feature where when a user displays the formset and, say, updates 2 out of the 10 items, I can track just the 2 updated, and output a message like "You have updated 2 items" kind-of-thing.
Do Django Model Formsets have a built in API for this? I can't seem to find it on the Django Docs.
I've tried various approaches but keep getting this when using the code offered by Peter below:
'Attendance' object has no attribute 'has_changed.'
If I switch form.has_changed to formset.has_changed(), I get
'list' object has no attribute 'has_changed'
My View and Post method
class AttendanceView(TemplateView):
template_name = 'example.html'
def changed_forms(self, formset):
return sum(1 for form in formset if form.has_changed())
def post(self, request, *args, **kwargs):
formset = AttendanceFormSet(request.POST)
if formset.is_valid():
formset = formset.save()
forms_changed = self.changed_forms(formset)
context = self.get_context_data(**kwargs)
context['total_changed_forms'] = forms_changed
return self.render_to_response(context)
else:
return HttpResponse("POST failed")
So I figured it out, just change:
formset = formset.save()
to
formset.save()
Then in save method you can compare old and new value of field to check if the value has changed. @classmethod def from_db(cls, db, field_names, values): new = super(Alias, cls). from_db(db, field_names, values) # cache value went from the base new. _loaded_remote_image = values[field_names.
Set the exclude attribute of the ModelForm 's inner Meta class to a list of fields to be excluded from the form.
A formset is a layer of abstraction to work with multiple forms on the same page. It can be best compared to a data grid. Let's say you have the following form: >>> from django import forms >>> class ArticleForm(forms.
Use the has_changed() method on your Form when you need to check if the form data has been changed from the initial data.
Formsets have a has_changed
method which will report whether or not any of its forms have been changed. That's not exactly what you're looking for, but if you look at its implementation it should show you how to do it. That method is:
def has_changed(self):
"""
Returns true if data in any form differs from initial.
"""
return any(form.has_changed() for form in self)
So you can count changed forms with:
def changed_forms(formset):
return sum(1 for form in formset if form.has_changed())
Or if you're comfortable using the integer meanings of boolean values:
return sum(form.has_changed() for form in formset)
I personally find that unappealing compared to the more explicit mapping from true
to 1
, but opinions differ there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With