Django admin validation for inline form which rely on the total of a field between all forms

别说谁变了你拦得住时间么 提交于 2021-02-06 10:02:43

问题


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


回答1:


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)


来源:https://stackoverflow.com/questions/4735920/django-admin-validation-for-inline-form-which-rely-on-the-total-of-a-field-betwe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!