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_tweaksINSTALLED_APPSに追記します。

INSTALLED_APPS = [
    .....
    'widget_tweaks',
]

widget_tweaksのロード

フォームを出力したいテンプレートでwidget_tweaksをロードします。

{% load widget_tweaks %}

実装

widget_tweaksは2種類の方法を使ってフォームのデザインを調整します。

  1. 「add_class」テンプレートフィルター
  2. 「render_field」テンプレートタグ

今回はadd_classを使い、下図のようなシンプルだけどいい感じに整っているフォームを作ってみます。

Bootstrap4で綺麗に整えたdjangoのフォーム

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="{% url 'sign_up' %}" method="post">
  {% csrf_token %}

  <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' }}
      {% for error in form.username.errors %}
        <span class="help-block">{{ error }}</span>
      {% endfor %}
    </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' }}
      {% for error in form.email.errors %}
        <span class="help-block">{{ error }}</span>
      {% endfor %}
    </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' }}
      {% for error in form.password.errors %}
        <span class="help-block">{{ error }}</span>
      {% endfor %}
    </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のフォームを自由にカスタマイズできるようになりました。やったね!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください