Djangoのフォームデザインを簡単かつ自由にカスタマイズする方法
|
Djangoにはフォーム関連のフレームワークが強力でバリデーションをいい感じに行ってくれるのですが、デザイン面の調整が難しくて苦戦中です。
例えばCSSのクラスを付与したい時、次のようにバックエンド側に処理を書く必要があります。
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class SignUpForm(UserCreationForm):
username = forms.CharField(
max_length=100,
widget=forms.TextInput(attrs={'class': "form-control"}),
)
password = forms.CharField(widget=forms.PasswordInput)
直感的ではないので、この書き方はあまり好きではありません。デザインに関わるコードは可能な限りテンプレート側に直接記述したいですよね。
Bootstrap4やFoundationなどのCSSフレームワーク対応のライブラリなどいくつか試した結果、 django-widget-tweaks
というのが最も自由度が高く、HTMLライクに記述できて分かりやすかったため、情報をまとめます。
前準備
ライブラリのインストール
まず django-widdget-tweaks
をインストールします。ライブラリの情報は PyPI でチェックできます。
pip install django-widget-tweaks
settings.pyの編集
widget_tweaks
を INSTALLED_APPS に追記します。
INSTALLED_APPS = [
.....
'widget_tweaks',
]
widget_tweaksのロード
フォームを出力したいテンプレートで widget_tweaks をロードします。
{%!l(MISSING)oad widget_tweaks %!}(MISSING)
実装
widget_tweaksは2種類の方法を使ってフォームのデザインを調整します。
- 「add_class」テンプレートフィルター
- 「render_field」テンプレートタグ
今回は add_class を使い、下図のようなシンプルだけどいい感じに整っているフォームを作ってみます。
forms.pyの編集
特にCSS関連の情報を記述する必要はなく、スッキリかけます。
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class SignUpForm(UserCreationForm):
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username', 'email', 'password')
テンプレートの編集
HTMLライクにストレスなくコーディングできます。
{{ form.hogehoge|add_class:'form-control' }}
の部分がライブラリのルールに沿ったコードです。
<form action="{%!u(MISSING)rl 'sign_up' %!}(MISSING)" method="post">
{%!c(MISSING)srf_token %!}(MISSING)
<div class="form-group row">
<label for="{{ form.username.id_for_label }}" class="col-sm-3 col-form-label">ユーザー名</label>
<div class="col-sm-9">
{{ form.username|add_class:'form-control' }}
{%!f(MISSING)or error in form.username.errors %!}(MISSING)
<span class="help-block">{{ error }}</span>
{%!e(MISSING)ndfor %!}(MISSING)
</div>
</div>
<div class="form-group row">
<label for="{{ form.email.id_for_label }}" class="col-sm-3 col-form-label">メールアドレス</label>
<div class="col-sm-9">
{{ form.email|add_class:'form-control' }}
{%!f(MISSING)or error in form.email.errors %!}(MISSING)
<span class="help-block">{{ error }}</span>
{%!e(MISSING)ndfor %!}(MISSING)
</div>
</div>
<div class="form-group row">
<label for="{{ form.password1.id_for_label }}" class="col-sm-3 col-form-label">パスワード</label>
<div class="col-sm-9">
{{ form.password1|add_class:'form-control' }}
{%!f(MISSING)or error in form.password.errors %!}(MISSING)
<span class="help-block">{{ error }}</span>
{%!e(MISSING)ndfor %!}(MISSING)
</div>
</div>
<hr>
<div class="form-group row">
<div class="col-sm">
<button type="submit" class="btn btn-info btn-block">登録</button>
</div>
</div>
</form>
まとめ
Djangoのフォームを自由にカスタマイズできるようになりました。やったね!