iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 18
0
Modern Web

加速你的 Django 網站開發 - Django 的好用套件系列 第 18

18. django-crispy-forms

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 無法做到的。


上一篇
17. django-model-utils
下一篇
19. django-mptt
系列文
加速你的 Django 網站開發 - Django 的好用套件30

尚未有邦友留言

立即登入留言