Django 的 form 很強大,但缺點是,要弄的好看,得自己寫 HTML,一個欄位一個欄位寫。前面有介紹過 django-bootstrap4 ,它可以讓 form 變得美觀。今天要介紹的是另外一個套件,叫作 django-cripsy-forms ,跟 django-bootstrap4 相比,它有更高的彈性。
事實上,我是先接觸 django-crispy-forms 以後,才又碰到 django-bootstrap4 的。
專案網址:https://django-crispy-forms.readthedocs.io/en/latest/
poetry add django-cripsy-forms
INSTALLED_APPS = (
...
'crispy_forms',
)
使用的方法蠻簡單的,首先在 template 裡載入:
{% load crispy_forms_tags %}
接著使用 template filter
<form method="post">
{{ form|crispy }}
</form>
這樣就可以輸出一個符合 bootstrap 樣式的表單了。
如果需要自訂 Form 的輸出,可以使用 FormHelper。
讓我們先定義一個 Form
from django import forms
class ExampleForm(forms.Form):
like_website = forms.TypedChoiceField(
label = "Do you like this website?",
choices = ((1, "Yes"), (0, "No")),
coerce = lambda x: bool(int(x)),
widget = forms.RadioSelect,
initial = '1',
required = True,
)
favorite_food = forms.CharField(
label = "What is your favorite food?",
max_length = 80,
required = True,
)
然後在 ExampleForm 裡增加 __init__
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_id = 'id-exampleForm'
self.helper.form_class = 'blueForms'
self.helper.form_method = 'post'
self.helper.form_action = 'submit_survey'
self.helper.add_input(Submit('submit', 'Submit'))
__init__
裡,我們指定了 form 的 id, class, method 跟 action,另外也增加了一個 submit 按鈕。
在 Template 裡面寫
{% load crispy_forms_tags %}
{% crispy form %}
這時候,我們不用再額外寫 <form>
,因為 crispy 除了會輸出原本 form 的欄位之外,也會依據 __init__
內的程式,額外輸出 <form action="/submit/survey/" method="post" id="id-exampleForm">
、 <input type=submit value=Submit>
。
上面提到 FormHelper 可以加 submit 按鈕,調整 form 屬性之外,也可以調整布局,像下面這段程式,就使用了四個 FieldSet 去幫欄位做分組
class SForm(forms.Form):
rate_1_1 = forms.CharField(label='rate_1_1')
rate_1_2 = forms.CharField(label='rate_1_2')
rate_1_3 = forms.CharField(label='rate_1_3')
rate_1_4 = forms.CharField(label='rate_1_4')
rate_2_1 = forms.CharField(label='rate_2_1')
alarm_sound = forms.CharField(label='alarm_sound')
timezone = forms.CharField(label='timezone')
def __init__(self, *args, **kwargs):
helper = FormHelper()
helper.form_class = 'form-horizontal'
helper.label_class = 'col-sm-3'
helper.field_class = 'col-sm-9'
layout_args = [
Fieldset("Site title", "title"),
Fieldset(
"Display",
Div(HTML("Unit: second"), css_class='text-right'),
'rate_1_1',
'rate_1_2',
'rate_1_3',
'rate_1_4',
Div(HTML("Unit: minute"), css_class='text-right'),
"rate_2_1",
),
Fieldset(
"Alarm sound",
'alarm_sound'
),
Fieldset("Timezone", "timezone"),
]
helper.layout = Layout(*layout_args)
self.helper = helper
# ... other code ...
我使用 django-crispy-forms 的主要原因是可以動態的調整 form 的 action, method, id ,甚至 css class 跟布局,而這些是使用 Django form 無法做到的。