Django Formset - проверить ввод на основе пользовательских куки?

У меня есть форма Django (TestForm), которая содержит одно поле, количество. У меня также есть набор форм Django (TestFormset), который содержит несколько экземпляров моей TestForm.

Я хочу написать собственный метод clean() для моего TestFormset, который проверяет, что сумма величин, указанных в моих нескольких TestForms, равна числу max_quantity, хранящемуся в переменной сеанса.

Я знаю, что могу выполнить эту проверку в пределах views.py (например, после того, как мой набор форм проверен и очищен, я мог бы вручную суммировать переменные "количества" в моих тестовых формах и проверять, чтобы они соответствовали запросу. сеанс ['max_quantity'], выдавая ошибку, если обнаружены какие-либо проблемы).

Но в идеале я хотел бы перенести всю мою логику проверки формы в метод clean() формы. Однако я не могу понять, как передать внешнее значение в мой набор форм, которое не связано ни с одной из его отдельных форм.

Возможно ли это сделать?

forms.py

from django.forms import BaseFormSet

class TestForm(forms.Form):
    quantity = forms.IntegerField()

class BaseTestFormset(BaseFormset):
    def clean(self):
        if any(self.errors):

            # Don't bother validating the formset unless each form is valid on its own

            return

        quantity = 0

        for form in self.forms:
            quantity += form.cleaned_data['quantity']

        # IF QUANTITY IS NOT EQUAL TO MAX_QUANTITY, THROW AN ERROR...
        # ...BUT HOW DO WE GET THE MAX_QUANTITY INTO THIS FUNCTION?

views.py

from .forms import TestForm, BaseTestFormset

def serve_form(request):

    TestFormSet = formset_factory(TestForm, formset=BaseTestFormset)

    if request.method == 'POST':
        formset = TestFormSet(request.POST)

        # This method should check to ensure that the sum of quantities within our formsets does not exceed max_quantity
        if formset.is_valid():
              # Proceed to take action
    else:
        # Sample initial data
        formset = TestFormSet(initial=[{'quantity': 5}, {'quantity': 7}])

    # I CAN PASS MAX_QUANTITY INTO THE TEMPLATE... BUT HOW DO I GET IT INTO THE FORMSET VALIDATION METHOD?
    return render(request, 'template.html', {'formset': formset, 'max_quantity': request.session['max_quantity']}

1 ответ

Решение

Как и в случае с формами, если вы хотите получить доступ к чему-либо в методе, вам нужно передать его куда-нибудь. Вы можете сделать это в инициализаторе, если хотите:

class BaseTestFormset(forms.BaseFormSet):
    def __init__(self, *args, **kwargs):
        self.max_quantity = kwargs.pop('max_quantity', None)
        super(BaseTestFormset, self).__init__(*args, **kwargs)

    def clean(self):
        ...
        if quantity > self.max_quantity:
            ...

и в представлении:

if request.method == 'POST':
    formset = TestFormSet(request.POST, max_quantity=request.session['max_quantity'])
Другие вопросы по тегам