The django docs cover cleaning and validating FIELDS that depend on each other, but I can't find anything that covers forms that depend on each other.
django文档涵盖了相互依赖的清理和验证FIELDS,但我找不到任何涵盖彼此依赖的形式的内容。
I have a single HTML form with which contains both a standard django form and a django formset. Proper validation of each form in the formset is entirely conditional based on a value from the main form (e.g. check a box on the main form, and a specific field on each form in the formset suddenly becomes required).
我有一个HTML表单,其中包含标准的django表单和django表单集。对表单集中每个表单的正确验证完全是基于主表单中的值的条件(例如,检查主表单上的框,并且突然需要在表单集中的每个表单上的特定字段)。
My intuition is to "simply" pass the entire main form into the formset validation call, like so:
我的直觉是“简单地”将整个主窗体传递给formset验证调用,如下所示:
def my_view(request):
MyFormSet = formset_factory(MyForm, extra=2, can_order=True)
if request.method == 'POST':
form = MainForm(request.POST)
formset = MyFormSet(request.POST)
if form.is_valid() and formset.is_valid(form): # <-- ?!?!
# The formset is now validated based on the form
However, to make that work, I believe I would have to override both the formset is_valid()
along with the underlying form is_valid()
and clean()
method. So, it gets pretty messy pretty quick.
但是,为了做到这一点,我相信我必须覆盖formset is_valid()以及底层表单is_valid()和clean()方法。所以,它变得相当混乱很快。
Is there a better way to do this?
有一个更好的方法吗?
2 个解决方案
#1
8
I investigated doing something like this once, and this tutorial http://yergler.net/blog/2009/09/27/nested-formsets-with-django/ was fairly helpful.
我曾经调查了这样的事情,本教程http://yergler.net/blog/2009/09/27/nested-formsets-with-django/非常有帮助。
Another way to do this is:
另一种方法是:
def my_view(request):
MyFormSet = formset_factory(MyForm, extra=2, can_order=True)
if request.method == 'POST':
form = MainForm(request.POST)
formset = MyFormSet(request.POST, other_form = form)
if form.is_valid() and formset.is_valid(): # <-- ?!?!
# The formset is now validated based on the form
Then
class MyFormSet(...):
def __init__(self, *args, **kwargs):
if kwargs.has_key('other_form'):
self.myformforlater = kwargs.pop('other_form')
Super(MyFormSet, self).__init__(*args, **kwargs)
This way you only have to override the init method, and you have access to the outer form from any validation step.
这样,您只需覆盖init方法,并且可以从任何验证步骤访问外部表单。
#2
6
Here's the code I ended up with, using Ted's answer (django 1.3):
这是我最终得到的代码,使用Ted的答案(django 1.3):
class BaseMyFormSet(BaseFormSet):
main_form = None
def __init__(self, *args, **kwargs):
# Save the main form until validation
if kwargs.has_key('main_form'):
self.main_form = kwargs.pop('main_form')
super(BaseMyFormSet, self).__init__(*args, **kwargs)
def clean(self):
if any(self.errors):
# Don't bother validating the formset unless each
# form is valid on its own
return
checkbox = self.main_form.cleaned_data['my_checkbox']
if checkbox:
for form in self.forms:
# Do some extra validation
def my_view(request):
MyFormSet = formset_factory(MyForm, extra=2, can_order=True,
formset=BaseMyFormSet)
if request.method == 'POST':
form = MainForm(request.POST)
formset = MyFormSet(request.POST, main_form=form)
if form.is_valid() and formset.is_valid():
# The formset is now validated based on the form
#1
8
I investigated doing something like this once, and this tutorial http://yergler.net/blog/2009/09/27/nested-formsets-with-django/ was fairly helpful.
我曾经调查了这样的事情,本教程http://yergler.net/blog/2009/09/27/nested-formsets-with-django/非常有帮助。
Another way to do this is:
另一种方法是:
def my_view(request):
MyFormSet = formset_factory(MyForm, extra=2, can_order=True)
if request.method == 'POST':
form = MainForm(request.POST)
formset = MyFormSet(request.POST, other_form = form)
if form.is_valid() and formset.is_valid(): # <-- ?!?!
# The formset is now validated based on the form
Then
class MyFormSet(...):
def __init__(self, *args, **kwargs):
if kwargs.has_key('other_form'):
self.myformforlater = kwargs.pop('other_form')
Super(MyFormSet, self).__init__(*args, **kwargs)
This way you only have to override the init method, and you have access to the outer form from any validation step.
这样,您只需覆盖init方法,并且可以从任何验证步骤访问外部表单。
#2
6
Here's the code I ended up with, using Ted's answer (django 1.3):
这是我最终得到的代码,使用Ted的答案(django 1.3):
class BaseMyFormSet(BaseFormSet):
main_form = None
def __init__(self, *args, **kwargs):
# Save the main form until validation
if kwargs.has_key('main_form'):
self.main_form = kwargs.pop('main_form')
super(BaseMyFormSet, self).__init__(*args, **kwargs)
def clean(self):
if any(self.errors):
# Don't bother validating the formset unless each
# form is valid on its own
return
checkbox = self.main_form.cleaned_data['my_checkbox']
if checkbox:
for form in self.forms:
# Do some extra validation
def my_view(request):
MyFormSet = formset_factory(MyForm, extra=2, can_order=True,
formset=BaseMyFormSet)
if request.method == 'POST':
form = MainForm(request.POST)
formset = MyFormSet(request.POST, main_form=form)
if form.is_valid() and formset.is_valid():
# The formset is now validated based on the form