サイドバーの「Django ドキュメント検索」というプレースホルダの入った検索では、Django ドキュメント (Django 2.1) の公式サイト内を検索できます
Django で Admin 画面の日付入力 Widget を利用するには

目次

はじめに

ユーザに日付を入力してもらうインターフェースとしてカレンダーを使いたいというケースは多いと思います。

HTML5 であれば <input type="date"> としておいて描画はブラウザにまかせるのが手っ取り早いかもしれません。HTML5 に限定できない場合は、 "datepicker" 等をキーワードにして探せば複数の JavaScript ライブラリを見つけることが可能だと思います。

一方で、Django の特徴の1つである管理画面作成機能を使った事がある方ならば、管理画面では日付フィールドを含むモデルの追加 / 編集の際にカレンダーを使えることにお気づきかと思います。例えば以下のような感じです。

 

カレンダーのアイコンをクリックすることによって、カレンダーから日付を入力する事が可能です。

このカレンダーは AdminDateWidget を利用することで実現できます。
そこで、この記事では UI で AdminDateWidget を利用してカレンダー入力を実現するための手順についてまとめました。

必要な手続き

AdminDateWidget でカレンダー入力を行うためには、下記手続きが必要です。

  1. DateField のウィジェットとして AdminDateWidget を指定する。
  2. テンプレートのヘッダ内でフォームの media 属性を表示する。
  3. 2 で不足する Admin 画面のスタイルシート、JavaScript ファイルをヘッダ内に追加する。

AdminDateWidget を指定する

Model を使わない場合

まずは Model を定義せずに、純粋に Form だけを定義する場合を考えてみます。

date_field という日付フィールドのあるフォーム (DateForm) を作成してみます。

from django import forms
from django.contrib.admin.widgets import AdminDateWidget


class DateForm(forms.Form):
    date_field = forms.DateField(widget=AdminDateWidget())

フィールドを定義する際に widget 引数で AdminDateWidgets() を割り当てます。

Model を使う場合

次に Model が定義されていて、対応するフォームを表示するケースも考えてみます。

下記のモデルが定義されているとします。

from django.db import models


class DateModel(models.Model):
    date_field = models.DateField()

このモデルに対するフォームを定義する場合には、ModelForm を使うことになると思います。

from django import forms
from django.contrib.admin.widgets import AdminDateWidget
from .models import DateModel


class DateForm(forms.ModelForm):
    class Meta:
        model = DateModel
        fields = ('date_field',)
        widgets = {
            'date_field': AdminDateWidget(),
        }

class Meta の中で、widgets 属性で 'date_field' のウィジェットを定義しています。

media 属性を描画する

ここでは、実験用として下記のような簡単なビューを用意します。

from django.shortcuts import render
from .forms import DateForm


def index(request):
    context = {
        'form': DateForm()
    }
    return render(request, 'use_admin_widgets/index.html', context)

コンテキスト変数 'form' で DateForm を指定、テンプレートとして index.html を指定しています。

Django ではフォームの media 属性にフォームが依存する css や JavaScript のリストのリストが格納されていますので、テンプレートのヘッダフィールド内でこれを描画します。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    {{ form.media }}

</head>
<body>
{{ form }}
</body>
</html>

実際に描画すると、{{ form.media }} の箇所は、下記で置き換えられます。

<script type="text/javascript" src="/static/admin/js/vendor/jquery/jquery.js"></script>
<script type="text/javascript" src="/static/admin/js/jquery.init.js"></script>
<script type="text/javascript" src="/static/admin/js/calendar.js"></script>
<script type="text/javascript" src="/static/admin/js/admin/DateTimeShortcuts.js"></script>

 

この状態ではまだカレンダーは表示されません。

足りないスタイルシートと JavaScript を追加する

先の処置で不足するスタイルシート等を追加したテンプレートは下記のようになります。

{% load static %}<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <!-- for admin widgets -->
    <link rel="stylesheet" type="text/css" href="{% static 'admin/css/base.css' %}"/>
    <link rel="stylesheet" type="text/css" href="{% static 'admin/css/forms.css' %}"/>

    <script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
    {{ form.media }}
    <script type="text/javascript" src="{% static 'admin/js/core.js' %}"></script>
    <script type="text/javascript" src="{% static 'admin/js/admin/RelatedObjectLookups.js' %}"></script>
    <!-- end for admin widgets -->

</head>
<body>
{{ form }}
</body>
</html>

追加するタグで使用する URL で {% static %} タグを使うために、最初に {% load static %} を記述しておきます。

ヘッダ内に追加する必要のあるタグは、<!-- for admin widgets --> から <!-- end for admin widgets --> に書かれた部分です。

これで下記のように表示されます。

カレンダー部分をクリックすると、下記のようなカレンダーが表示されて入力が可能になります。

以上で、Admin 画面で使用されているカレンダーウィジェットを使用した日付入力を利用できます。

JavaScript逆引きレシピ 第2版 (PROGRAMMER’S RECiPE)

参考

Integrate calendar widget in Django app - Stack Overflow

低価格なのに高速・多機能・高セキュリティ 月額400円(税別)から最大容量100GB WordPress専用高速サーバー Z.com WP
おすすめの記事