【问题标题】:Django formset - validate input based on user cookie?Django formset - 根据用户cookie验证输入?
【发布时间】:2018-05-28 17:42:28
【问题描述】:

我有一个包含单个字段数量的 Django 表单 (TestForm)。我还有一个 Django formset (TestFormset),其中包含我的 TestForm 的多个实例。

我想为我的 TestFormset 编写一个自定义 clean() 方法,以验证我的多个 TestForms 中指定的数量之和是否等于存储在会话变量中的一个数字 max_quantity。

我知道我能够在 views.py 中执行此验证(例如,在我的表单集经过验证和清理后,我可以手动总结我的 TestForms 中的“数量”变量并检查以确保它们相等到 request.session['max_quantity'],如果发现任何问题抛出错误)。

但理想情况下,我希望将所有表单验证逻辑移至 forms.py 的 clean() 方法中。但是,我不知道如何将外部值传递到我的 Formset 中,该值未链接到其单个表单之一。

这样可以吗?

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']}

【问题讨论】:

    标签: django forms validation django-forms formsets


    【解决方案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'])
    

    【讨论】:

    • 当然!这很有意义。谢谢一百万:)
    猜你喜欢
    • 2011-01-27
    • 2021-12-15
    • 1970-01-01
    • 2017-04-19
    • 1970-01-01
    • 2014-06-29
    • 2013-02-02
    • 1970-01-01
    • 2017-06-08
    相关资源
    最近更新 更多