Проверка администратора Django для встроенной формы, которая основывается на общем поле между всеми формами

Простите меня, если на это был дан ответ раньше, я не смог найти ответ, где проверка зависела от совокупности встроенных форм.

Небольшой фон: я занимаюсь сайтом для страхового брокера, который имеет "Политику" и "Итоговую комиссию" этой политики. Есть также "реселлеры", которые добавляются в "Политику" вместе с комиссией, которая идет к ним (может иметь любое количество реселлеров). Общая комиссия между реселлерами должна быть меньше общей комиссии.

У меня есть admin.ModelForm для политики, а ниже у меня есть admin.InlineTabular, который может иметь несколько реселлеров через кнопку "Добавить", и все это работает отлично.

Однако я не могу понять, как сделать валидацию на них, так что я могу в принципе скомпоновать все комиссии, а затем, если это больше, чем общая комиссия, запустите ValidationError.

Я попробовал clean(), но не знаю, как получить доступ к очищенным данным InlineTabular, если он даже доступен!

Заранее благодарим за помощь!

Томас

Ответ 1

Я знаю, что вопрос был задан давно, но поскольку я боролся с той же проблемой, я думаю, что это может быть полезно.

Ключевым моментом здесь является определение настраиваемого набора форм для вставки в табличную форму администратора, а затем для переопределения чистого метода formet.

Вот пример: композиция состоит из составных элементов, каждый составной элемент имеет поле процента, и я хочу проверить, что общий процент равен 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)