Django 向导表单中的条件表单字段

Posted

技术标签:

【中文标题】Django 向导表单中的条件表单字段【英文标题】:Conditional Form Field in Django wizard form 【发布时间】:2019-11-22 23:57:36 【问题描述】:

我在 django 中使用向导表单。仅当对其他表单字段的回答标记为“是”时,我才想创建一个表单字段,否则我不想要这个新的表单字段。我该怎么做? 我已经尝试了一些与此相关的其他答案,但其中大多数都讲述了如何标记字段是否必填,但我只想在其他字段的答案为“是”时才显示该字段

Django Form Wizard with Conditional Questions

在下面的代码中,我只想在对字段“Pool”的回答标记为“是”时才显示字段“Pool2”,否则我不想要该字段。如果用户家中有游泳池,基本上我想在“Pool2”字段中获取一些游泳池的详细信息。

forms.py

class ListingForm2(forms.Form):
     Pool = (
        ("Yes","Yes"),
        ("No","No"),
    )
    Pool = forms.ChoiceField(choices = Pool,label = "Does your property have a pool ?")
    Pool2 = forms.CharField(required=False)

Views.py

class ListingWizard(SessionWizardView):
    template_name = 'listing_form.html'
    form_list = [ListingForm1,ListingForm2,ListingForm3,ListingForm4]
    def done(self, form_list, **kwargs):
        save_data(form.cleaned_data for form in form_list)
        return render(self.request,'done.html',
            'form_data' : [form.cleaned_data for form in form_list],
            )

【问题讨论】:

使用 javascript 显示和隐藏字段,更改选择字段。 除了使用javascript别无他法?@Shubhitgarg 由于您希望在客户端进行一些更改,因此此处需要 javascript 或 css 好的谢谢@PRMoureu 【参考方案1】:

你想要做的事情必须用 JavaScript 来完成,你可以只用 Django 帖子来做,但这不是正确的方法。

看看这个:

class BookForm(forms.ModelForm):
    has_sequel = forms.BooleanField(initial=True)

    class Meta:
        model = Book
        fields = ['author', 'length', 'has_sequel', 'sequel']

    class Media:
        js = ('book_form.js', )

    def clean(self):
        if self.cleaned_data['has_sequel'] and self.cleaned_data['sequel'] is None:
            raise ValidationError('You should indicate the sequel if the book has one.')


class BookView(FormView):
    template_name = 'book_form.html'
    form_class = BookForm
    success_url = '/done/'

此代码在表单中包含 Javascript,这样您可以使用自己的 Javascript 重用表单,Javascript 代码应该是这样的(您可能需要更改 javascript,具体取决于您在模板中打印表单的方式):

$(document).ready(function() 
    $('#id_has_sequel')[0].addEventListener('change', (event) => 
        let sequelField = $('#id_sequel').parents('p');
        if (event.target.checked) 
            sequelField.show();
         else 
            sequelField.hide();
        
    )
);

模板应该是这样的:

% load static %

<head>
    <title>Book form</title>

    <script src="% static 'jquery-3.4.1.min.js' %"></script>
     form.media 
</head>

<form method="post">% csrf_token %
     form.as_p 
    <input type="submit" value="Send message">
</form>

如果您有任何问题,请随时提出,但在没有 Javascript 的情况下尝试这样做不是一个好方法。你会发现一些 Django 小部件也会使用 Javascript。

【讨论】:

以上是关于Django 向导表单中的条件表单字段的主要内容,如果未能解决你的问题,请参考以下文章

有条件地只需要 Django 模型表单中的一个字段

Django 1.8 中的 Django 表单向导去了哪里?

如何显示作为最终 django 表单向导步骤输入的所有数据的预览?

django:如何在表单向导中使用 inlineformset?

django 表单向导中的自定义模板 - NameError

使用 Django 模型表单 + 表单向导 + Crispy - 不进行第二步