I am trying to raise ValidationError if a duplicate entry found in an inlineformset, just like in the docs: Custom formset validation I'm using a debugging tool and stepping through the code. It successfully reaches the line: raise ValidationError("Check Duplicate Entry")
, and subsequently, in the view it takes the else statement instead proceeding with if formset.is_valid
. I print(formset.non_form_errors) just as in the docs. However, the example in the docs returns a list at this stage with the error message inside it. In my case, I get <bound method BaseFormSet.non_form_errors of <django.forms.formsets.MyInlineFormSet object at 0x7fcc22e89610>>
The template renders with the form data but the validation error does not appear to say what is wrong. I'm missing something for sure. Any help appreciated.
class MyInlineFormSet(BaseInlineFormSet):
def __init__(self, *args, **kwargs):
super(MyInlineFormSet, self).__init__(*args, **kwargs)
for form in self.forms:
form.empty_permitted = False
def clean(self):
if any(self.errors):
return
mylist = []
for form in self.forms:
myfield_data = form.cleaned_data.get("myfield")
if myfield_data in mylist:
raise ValidationError("Check Duplicate Entry")
mylist.append(myfield_data)
My tempate just has this:
{% block content %}
<section class="container-fluid">
{% crispy form %}
</section>
{% endblock content %}
Side Note: Any field validation errors against specific fields do show up. But there I am writing the errors like so: self._errors["fieldname"] = self.error_class(["Error in field, please double check"])
Not sure why raise ValidationError is not working for the formset
SOLVED! My formset is a crsipy form within a crispy form. The overall form is rendered in the template linked to the view. But I should have mentioned, I have a separate template containing the markup for the formset.
<div class="row justify-content-center">
<div class="col-7">
{{ formset.management_form | crispy }}
{% for form in formset.forms %}
<h3>Form {{forloop.counter}}</h3>
{% crispy form %}
{% endfor %}
</div>
<br>
</div>
So I just needed to add {{ formset.non_form_errors }}
below formset.management_form.