Django フォームにて CSS クラスを設定する方法
以前の記事 「Django フォームの基本」等では、フォームの作成やデータ検証等の多くの機能が Django で自動化されることをみてきました。
しかし、ここで作成したフォームは見た目にさすがに格好悪く、このままでは使い物になりません。カスタマイズが必要です。
この記事では Django フォームに CSS クラスを設定する方法を説明します。CSS クラスが設定できればかなり自由に UI は調整可能になりますよね。
ついでにより実用的に Bootstrap も利用してみます。
DOM 属性の指定などはビューからでも可能ですが、ここではテンプレートで CSS クラスを操作する方法を紹介します。
django-widget-tweaks の利用
テンプレートで自在に DOM の属性等を操作するには、django-widget-tweaks が利用できます。MIT ライセンスです。
$ pip install django-widget-tweaks
インストールしたら settings.py の INSTALLED_APPS に widget_tweaks として追加します。
INSTALLED_APPS = [
'widget_tweaks',
...
]
django-widget-tweaks の基本的な使用方法
テンプレートのフィルターとして使います。
CSS クラスを設定するには、次のようにします。
{% load widget_tweaks %}
{{form.username|add_class:"form-control"}}
属性を追加するには次のようにします。
{{form.message|attr:"cols:40"|attr:"rows:20"}}
Django フォームと Bootstrap の使用例
ここでは Django フォームと Bootstrap と併せて利用する例を紹介します。
下記のコードサンプルで、次のような画面になります。
forms.py は次の通りです。
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(max_length=30)
password = forms.CharField(widget=forms.PasswordInput)
views.py は次の通りです。
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from myapp1.forms import LoginForm
def index(request):
return render(request, 'myapp1/page1.html')
def login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
if username == 'user1' and password == 'secret':
return HttpResponseRedirect('/myapp1/')
else:
return render(
request,
'myapp1/login.html',
{
'form':form,
'msg':'Authentication failed'
})
else:
return render(
request,
'myapp1/login.html',
{
'form':form,
'msg': 'Invalid data'
})
else:
form = LoginForm()
return render(
request,
'myapp1/login.html',
{'form':form, 'msg':''})
アプリケーション名を myapp1 としています。
テンプレートのベースとして base.html を次のようにします。ここで Bootstrap のスクリプト類を取り込んでしまいます。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Bootstrap Test</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
</head>
<body>
<div class="container">
{% block content1 %}
{% endblock %}
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</body>
</html>
次にログインフォームのテンプレートとして、次のコードを login.html とします。
{% extends "myapp1/base.html" %}
{% load widget_tweaks %}
{% block content1 %}
<div style="padding:1em;">
<div class="jumbotron">
<h1>Django Tutorial</h1>
<p>これは Django フォームに CSS クラスを設定する方法のデモです。ついでに bootstrap もやってます。</p>
</div>
<form method='POST' action='' class="form-horizontal">
{% csrf_token %}
{% if msg != '' %}
<div class="alert alert-danger" role="alert">
{{msg}}
</div>
{% endif %}
<div class='form-group'>
<label for='id_email' class="col-sm-4 control-label">Username:</label>
<div class='col-sm-8'>{{form.username|add_class:"form-control"}}</div>
</div>
<div class='form-group'>
<label for='id_password' class="col-sm-4 control-label">Password:</label>
<div class='col-sm-8'>{{form.password|add_class:"form-control"}}</div>
</div>
<div class='form-group'>
<div class='col-sm-8'><button type="submit" class="btn btn-primary">Login</button></div>
</div>
</form>
</div>
{% endblock %}
Bootstrap は CSS クラスを設定して使うフレームワークの一例として紹介しましたが、 他の多くのフレームワークでも CSS クラスをふんだんに使うのが一般的です。
ここで紹介した django-widget-tweaks があれば、テンプレートで柔軟に DOM の属性等を操作できるので大変便利です。