Forgive me if this has been answered before, I couldn't find an answer where the validation depended on the aggregate of inline forms.
Little background: I'm doing a site for an insurance broker which has 'Policies' and a 'Total Commission' of that policy. There are also 'Resellers' which are added to the 'Policy' along with a commission which goes to them (can have any number of resellers). The total commission between the resellers has to be less than the total commission.
I have an admin.ModelForm for a policy, and below I have a admin.InlineTabular which can have multiple resellers through the 'Add' button and this all works perfectly.
However, I can't seem to figure out how to do validation on them, so that I can basically add up all the commissions and then if it is greater than the total commission throw a ValidationError.
I've tried clean() but don't know how to access the InlineTabular cleaned data if it is even available!
Thanks in advance for any help!
Thomas
The run_validators() method on a Field runs all of the field's validators and aggregates all the errors into a single ValidationError .
Django forms submit only if it contains CSRF tokens. It uses uses a clean and easy approach to validate data. The is_valid() method is used to perform validation for each field of the form, it is defined in Django Form class. It returns True if data is valid and place all data into a cleaned_data attribute.
Set the exclude attribute of the ModelForm 's inner Meta class to a list of fields to be excluded from the form.
The admin interface is also customizable in many ways. This post is going to focus on one such customization, something called inlines. When two Django models share a foreign key relation, inlines can be used to expose the related model on the parent model page. This can be extremely useful for many applications.
I know the question was asked a long time ago, but since I struggled with the same problem, I think it might be usefull.
The key here is to define a custom formset to embed into the tabular admin form, then to override the formset clean's method.
Here's an example : a composition is made of composition_elements, each composition_element has a percent field, and I want to validate that the total percent is equal to 100.
from django import forms
from django.forms.models import BaseInlineFormSet
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from django.contrib import admin
from .models import Composition, CompositionElement
class CompositionElementFormSet(BaseInlineFormSet):
'''
Validate formset data here
'''
def clean(self):
super(CompositionElementFormSet, self).clean()
percent = 0
for form in self.forms:
if not hasattr(form, 'cleaned_data'):
continue
data = form.cleaned_data
percent += data.get('percent', 0)
if percent != 100:
raise ValidationError(_('Total of elements must be 100%%. Current : %(percent).2f%%') % {'percent': percent})
class CompositionElementAdmin(admin.TabularInline):
model = CompositionElement
formset = CompositionElementFormSet
class CompositionAdmin(admin.ModelAdmin):
inlines = (CompositionElementAdmin,)
admin.site.register(Composition, CompositionAdmin)
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