Django formset - 根据用户 cookie 验证输入?
Django formset - validate input based on user cookie?
我有一个包含单个字段数量的 Django 表单 (TestForm)。我还有一个 Django 表单集 (TestFormset),其中包含我的 TestForm 的多个实例。
我想为我的 TestFormset 编写一个自定义的 clean() 方法,以验证我的多个 TestForm 中指定的数量总和是否等于一个数字 max_quantity,存储在一个会话变量中。
我知道我可以在 views.py 内执行此验证(例如,在验证和清理我的表单集后,我可以手动汇总我的 TestForms 中的 'quantity' 变量并检查确保它们等于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']}
与表单一样,如果您想访问方法中的某些内容,则需要将其传递到某个地方。如果您愿意,可以在初始化程序中执行此操作:
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'])
我有一个包含单个字段数量的 Django 表单 (TestForm)。我还有一个 Django 表单集 (TestFormset),其中包含我的 TestForm 的多个实例。
我想为我的 TestFormset 编写一个自定义的 clean() 方法,以验证我的多个 TestForm 中指定的数量总和是否等于一个数字 max_quantity,存储在一个会话变量中。
我知道我可以在 views.py 内执行此验证(例如,在验证和清理我的表单集后,我可以手动汇总我的 TestForms 中的 'quantity' 变量并检查确保它们等于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']}
与表单一样,如果您想访问方法中的某些内容,则需要将其传递到某个地方。如果您愿意,可以在初始化程序中执行此操作:
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'])