问题 Django脆皮形式分裂场布局


我们有一个脆弱的形式,我们希望能够在表单的不同部分呈现不同的字段 HTML 模板,但是我们找不到这样做的方法 脆弱的文档。下面是一些略微编写的代​​码,用于说明我们要做的事情:

forms.py

helper = FormHelper()
helper.layout_1 = Layout(
    Div(
        Field('field_1a'),
        Field('field_1b')
    )
)
helper.layout_2 = Layout(
    Div(
        Field('field_2a'),
        Field('field_2b')
    )
)

template.html

<body>
    {% crispy form layout_1 %}
    <!-- A big bunch of other html -->
    {% crispy form layout_2 %}
</body>

有谁知道实现这一目标的干净方法?


到目前为止我们已经看过的方法必须排除:

  • 我们可以在HTML中手动添加字段,而不是为我们提供crispy渲染。然而,这似乎是一个禁忌,因为我们有一些 choice 选项以编程方式确定的字段。
  • 我们可以写一个使用了一个脆弱的布局 crispy.forms.layout.HTML 对象包括HTML,它分割我们布局的两个不同部分。但是,有很多HTML,如果我们将它直接嵌入到python中,将很难维护。
  • 我们可以写一个 自定义布局对象 为我们这样做,但我们预测这将涉及很多,并希望将此视为最后的手段。
  • 我们可以不使用crispy,而是寻找除了crispy之外的方法来实现这一点,但是然后我们将失去与我们的应用程序中的所有其他形式的一致性。

10572
2017-07-22 10:40


起源

这是一个 ModelForm 你在和谁合作? - Scott Woodall
不,它只是一个香草 django.forms.Form - robjohncox
那么,所有字段的清脆渲染是两次,而不仅仅是您在每个布局中指定的那些字段吗?我没有看到你当前的解决方案有什么问题。 - Scott Woodall
我们在布局的不同部分渲染不同的字段。上面的代码实际上并不起作用 - 这更像是为了说明我们想要尝试和做的事情(如果不够清楚则道歉) - robjohncox


答案:


更新:这不起作用 forms.ModelForm

尝试创建两个帮助程序而不是两个布局,然后显式调用单独的帮助程序。这样做你必须手动编写 <form> 用于将两个表单封装在模板中的标记,但希望能够提供所需的解决方案。

forms.py

class Form(forms.Form):
    field_1a = forms.CharField()
    field_1b = forms.CharField()
    field_2a = forms.CharField()
    field_2b = forms.CharField()

    def __init__(self, *args, **kwargs):
        super(Form, self).__init__(*args, **kwargs)
        helper1 = FormHelper()
        helper1.form_tag = False
        helper1.layout = Layout(
            Div(
                Field('field_1a'),
                Field('field_1b')
            )
        )

        helper2 = FormHelper()
        helper2.form_tag = False
        helper2.disable_csrf = True
        helper2.layout = Layout(
            Div(
                Field('field_2a'),
                Field('field_2b')
            )
        )

然后在你的模板中:

<body>
<form>
{% crispy form form.helper1 %}
<!-- A big bunch of other html -->
{% crispy form form.helper2 %}
</form>
</body>

15
2017-07-22 11:39



非常感谢斯科特,正是我所寻找的。 - robjohncox
哦,不需要创建类?好答案 - simple_human
@scott我正在尝试这个,但问题是第二个帮助器渲染(再次)字段也在第一个帮助器中。有什么线索吗? - JV.
使用ModelForm时,这不起作用。每个表单字段都由每个帮助程序输出,尽管布局中包含哪些字段。 - Eron Villarreal
@EronVillarreal for ModelForms你可以做一个 if hasattr(self.Meta, 'fields'): delattr(self.Meta, 'fields') 在结束时 __init__ 阻止破解你的方式 - Ian Clark


创建一个form.py

from crispy_forms.helper import FormHelper
from crispy_forms.layout import Field,Layout, ButtonHolder, Submit
class layout1Form(forms.Form):    
    def __init__(self, *args, **kwargs):
        super(layout1Form, self).__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.layout = Layout(
           Field('answer',css_class="field span8"),
           ButtonHolder(
              Submit('submit', 'Submit', css_class='btn-primary pull-right')
            )
          )
        self.helper.form_tag = False

class layout2Form(forms.Form):    
    def __init__(self, *args, **kwargs):
        super(layout1Form, self).__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.layout = Layout(
           Field('answer',css_class="field span8"),
           ButtonHolder(
              Submit('submit', 'Submit', css_class='btn-primary pull-right')
            )
          )
        self.helper.form_tag = False

然后在views.py中

views.py

from ...forms import layout1Form,layout2Form
def layouttest(request):
    form = layout1Form(request.POST)
    form1=layout2Form(request.POST)
    return render(request,'test.html',{'frm1':form,'frm2':form1})

然后在您可以使用的模板中

的test.html

<form id="signup" class="form-horizontal" method="post" action="">
{% crispy frm1 %}
   ""the big html""
{% crispy frm2 %}
<button type="submit" class="btn btn-success">Submit</button>   
</form>

1
2017-07-22 11:09



感谢您的建议@suhail,我们考虑过使用HTML元素,但是我们在布局的不同部分之间有很多HTML,并且希望避免将这么多HTML嵌入到python代码中(因为它将更难维护) HTML)。 - robjohncox
@robjohncox可能是你可以使用的模板 self.helper['<fieldname>'].wrap(Field, template="<template path>") - simple_human
有趣的是,看起来它可以工作。我们可能只是这样 - 等待看看人们可能有什么其他建议。 - robjohncox
@robjohncox我已经通过其他方式更新了我的答案。实际上我正在使用crispyforms。这些都来自我的工作项目 - simple_human
啊,所以它可以分成两种形式,这是有道理的。对于我们的用例,另一种方法(来自@scottwoodall)更合适,但仍然是一个简洁的解决方案,所以+1给你。 - robjohncox