【问题标题】:Django: Cleaning and validating FORMS that depend on each otherDjango:清理和验证相互依赖的表格
【发布时间】:2011-10-26 21:27:51
【问题描述】:

django 文档涵盖 cleaning and validating FIELDS that depend on each other,但我找不到任何涵盖相互依赖的表单的内容。

我有一个 HTML 表单,其中包含标准 django 表单和 django 表单集。 formset 中每个表单的正确验证完全取决于主表单中的值(例如,选中主表单上的一个框,以及 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

但是,为了实现这一点,我相信我必须同时覆盖表单集 is_valid() 以及基础表单 is_valid()clean() 方法。所以,它很快就会变得非常混乱。

有没有更好的方法来做到这一点?

【问题讨论】:

    标签: django validation django-forms


    【解决方案1】:

    我曾经研究过这样做,本教程http://yergler.net/blog/2009/09/27/nested-formsets-with-django/ 非常有帮助。

    另一种方法是:

    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
    

    然后

    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)
    

    这样您只需要重写 init 方法,并且您可以从任何验证步骤访问外部表单。

    【讨论】:

    • 这让我获得了 80% 的解决方案,所以我接受了它,但也发布了我的完整解决方案以供参考。
    【解决方案2】:

    这是我最终得到的代码,使用 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
    

    【讨论】:

      猜你喜欢
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-17
      • 2016-01-10
      • 1970-01-01
      相关资源
      最近更新 更多