Bootstrapはフロントエンド向けのツールキットです。
getbootstrap.com
BootstrapにはCSSやJavaScriptが用意されていて、ウェブページに組み込む場合は、HTMLタグにclass属性を指定すると、用意されているデザインが適用される、というものです。
メジャーバージョン間で互換性のない変更があり、Bootstrap4(バージョン 4.x)、Bootstrap5(バージョン 5.x)のようにメジャーバージョンの番号付きで呼ばれることがあります。
DjangoでBootstrapを使うには
BootstrapはHTMLタグにclass属性を指定できれば使えるので、DjangoでもテンプレートでCSSとJavaScriptを読み込むように記述すれば使えます。
しかし、DjangoのForm機能を使う場合、inputタグなどのform内で利用するHTMLの文字列生成は、アプリ側のテンプレートではなくDjango内部で行われるので、出力されるタグにclass属性を付与するには少し工夫が必要です。
この記事では説明しませんが以下の方法などがあります。
- widgetのテンプレートファイルを作成し、優先で使われるようにテンプレートローダーを設定する
- Formクラスを使う際に、フィールドのwidgetにattrsでclass属性を指定する
いくつかある方法のうち、テンプレートタグを使ってDjangoのformの出力内容を変更するアプローチで実装されてるのが django-bootstrap5 です。
django-bootstrap5 24.2 documentation
django-bootstrap5を使うと手軽にBootstrapをDjangoに組み込めます。
インストール
Installation - django-bootstrap5 24.2 documentation
PyPIからインストールできます。
pip install django-bootstrap5
INSTALLED_APPSに django_bootstrap5
を追加します。
INSTALLED_APPS = [
'django_bootstrap5',
]
INSTALLED_APPSへの追加は、ライブラリ内に含まれるテンプレートファイルや、テンプレートタグを使用するために必要な作業です。
導入
Quickstart - django-bootstrap5 24.2 documentation
ドキュメントからリンクされていますが、exampleのアプリを参考にするとわかりやすかったです。
django-bootstrap5/example at main · zostera/django-bootstrap5 · GitHub
Bootstrapはmetaタグでviewportの指定や、CSSファイル、JavaScriptファイルの読込みが必要になります。
Bootstrap側のドキュメントの通りにlinkタグやscriptタグを直接記述もできますが、django-bootstrap5では、ベースのテンプレートファイルが用意されています。
このファイルを継承して使っておくと、Bootstrapに関する各種設定変更をDjangoのsettings.pyからできるようになるのでおすすめです。
https://github.com/zostera/django-bootstrap5/blob/main/src/django_bootstrap5/templates/django_bootstrap5/bootstrap5.html
アプリ作成
例として myapp
を作ります。
python manage.py startapp myapp
FormとViewは特にbootstrap5を意識せずに、Djangoのドキュメント通りに作成します。
myapp/forms.py:
from django import forms
FAVORITE_COLORS_CHOICES = {
"blue": "Blue",
"green": "Green",
"black": "Black",
}
class MyForm(forms.Form):
name = forms.CharField(label="名前")
body = forms.CharField(label="本文", widget=forms.Textarea)
favorite_colors = forms.MultipleChoiceField(
required=False,
widget=forms.CheckboxSelectMultiple,
choices=FAVORITE_COLORS_CHOICES,
)
myapp/views.py:
from django.views.generic import TemplateView
from . import forms
class IndexView(TemplateView):
template_name = 'index.html'
def get_context_data(self):
return {'form': forms.MyForm()}
form
という名前のコンテキストで index.html
にDjango Formのインスタンスを渡しています。
URL設定
サンプルとして作成したプロジェクトは myproject
です。 myproject/urls.py
にルートのURL設定があります。
作成したIndexViewを有効にしておきます。
myproject/urls.py:
from django.contrib import admin
from django.urls import path
from myapp import views as myapp_views
urlpatterns = [
path('', myapp_views.IndexView.as_view()),
]
テンプレート作成
この例では myapp/templates ディレクトリ以下にファイルを作っていますが、実際に使用する場合はextendsに指定するテンプレートパスなどとの整合性がとれていれば、ここではなくてもよいです。
myapp/templates/bootstrap.html:
{% extends 'django_bootstrap5/bootstrap5.html' %}
{% block bootstrap5_title %}{% block title %}{% endblock %}{% endblock %}
django-bootstrap5に含まれるテンプレートファイルを継承して、プロジェクト内で使用するbootstrap用のベーステンプレートを作ります。titleブロックを定義しているので、継承したファイルでは bootstrap5_title
ブロックを使わずに、 title
ブロックで title部分を記載できます。exampleと同様です。
myapp/templates/base.html:
{% extends 'bootstrap.html' %}
{% load django_bootstrap5 %}
{% block bootstrap5_content %}
<div class="container">
<h1>{% block title %}(no title){% endblock %}</h1>
{% autoescape off %}{% bootstrap_messages %}{% endautoescape %}
{% block content %}(no content){% endblock %}
</div>
{% endblock %}
アプリ(プロジェクト)用のベーステンプレートです。各画面はこの base.html
を継承して作成する想定です。exampleを参考に必要な部分だけを記載しています。
myapp/templates/index.html:
{% extends 'base.html' %}
{% load django_bootstrap5 %}
{% block title %}
Bootstrap5 フォーム
{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
{% bootstrap_form form layout=layout size=size %}
{% bootstrap_button button_type="submit" content="OK" %}
{% bootstrap_button button_type="reset" content="Reset" %}
</form>
{% endblock %}
index.htmlでは django-bootstrap5 のテンプレートタグを使用しています。 bootstrap_formタグにformコンテキスト(IndexViewから渡されたMyFormのインスタンス)を渡して、class属性の付与などを行っています。
実行結果
ブラウザで http://127.0.0.1:8000/
にアクセスすると、Bootstrap5のデザインが適用されたフォームが表示されます。
サンプルコード全部
sample_nullpobug/django/django_bootstrap5 at main · tokibito/sample_nullpobug · GitHub