【Django】DateFieldをカレンダー入力に変更する方法

Django

(最終更新月:2021年10月)

前回の記事では、新たに追加したモデルフィールド「slug」へ関数でデフォルト値を設定する方法について解説しました

当記事では、次のステップとして作成日を保存する「date」フィールドを追加していきます

「date」フィールド追加の説明を通じて、

  • 新たなモデルフィールド「DateField」を追加する方法
  • カレンダーで日付を選択できる「datepicker」を追加する方法

を解説していきます

結果として、

と、日付の入力ボックスをクリックするとカレンダーが現れるようにしていきます

まずはフィールドを追加するところから順を追ってみていきましょう!

DateFieldの追加

nippo > models.py

from django.utils import timezone

class NippoModel(models.Model):
    #...
    date = models.DateField(default=timezone.now)
    #...

「date」フィールドに、defaultとして現在の時刻が保存されるように記述します

マイグレーションを行い完了です

OperationalError!となってしまいましたか?

その場合は下記に解決策がありますのでごらんください!

【dateフィールド追加時のフォーム】

通常の入力フォームで「年-月-日」といちいち入力しなければなりません

カレンダーを表示させていきましょう!

カレンダー表示「bootstrap-datepicker-plus」導入の流れ

bootstrapを元にしたモジュール「bootstrap-datepicker-plus」を使用しカレンダーを表示していきます

導入までの流れは下記の通りです

  1. bootstrap4をインストール、設定
  2. datepicker-plusをインストール、設定
  3. Formクラスの編集
  4. テンプレートの編集

まずは、datepicker-plusに必要なモジュール「bootstrap4」をインストール、設定するところから始めます

bootstrap4をインストール、導入

ターミナルで下記の通りインストール

$ pip install django-bootstrap4

インストールしたら、pip freezeで保存しておくことを忘れずに!

【settings.py】

INSTALLED_APPSに追記します

INSTALLED_APPS = [
    ....,
    ....,
    'bootstrap4',
    ....
]

TEMPLATES内「OPTIONS」にも追記が必要です

TEMPLATES = [
    {
        ....,
        'OPTIONS': {
            'context_processors': [
            ...,
            ],
            'builtins':[ 
                'bootstrap4.templatetags.bootstrap4',
            ],
        },
    },
]

jqueryを使う旨を宣言します

BOOTSTRAP4 = {
    'include_jquery': True,
}

「bootstrap4」のインストール、設定は完了しました!

次は、「bootstrap-datepicker-plus」をインストール、設定していきましょう!

「bootstrap-datepicker-plus」をインストール、導入

ターミナルでインストール

$ pip install django-bootstrap-datepicker-plus

【settings.py】

INSTALLED_APPSヘ追記が必要です

INSTALLED_APPS = [
    ...,
    'bootstrap_datepicker_plus',
    ...,
]

インストール、設定の完了!

pyファイル、テンプレートで表示するためのコードを書いていきます

フォームクラスの編集

nippo > forms.py

from bootstrap_datepicker_plus import DatePickerInput

class NippoModelForm(forms.ModelForm):
    date = forms.DateField(
        label="作成日",
        widget=DatePickerInput(format='%Y-%m-%d')
    )
    class Meta:
        #....
        #....

DatePickerInputをインポートし、

from bootstrap_datepicker_plus import DatePickerInput

「date」フィールドを上書きします

    date = forms.DateField(
        label="作成日",
        widget=DatePickerInput(format='%Y-%m-%d')
    )

完了です

次はテンプレートの編集です

テンプレートの編集

nippo-create.html

{{ form.as_p }}の手前に下記を追記shます

    {% bootstrap_javascript jquery='full' %} 
    {{ form.media }}

これによりjqueryとform.mediaを読み込み、「datepicker-plus」が表示できるようになります

【テンプレート全体】

{% extends 'base.html' %}

{% block content %}
<div class="container my-3" style="max-width:700px;">
    
    <div class="text-center my-3">
    {% if update %}
        <h2>{{ object }}の編集</h2>
    {% else %}
        <h2>新しく日報を作成</h2>
    {% endif %}
    </div>
    
    <form method="POST"> {% csrf_token %}
    {% bootstrap_javascript jquery='full' %} 
    {{ form.media }}
    {{ form.as_p }}
    {% if update %}
        <button class="btn btn-primary form-control" type="submit">保存</button>
        {% comment %} <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal"> {% endcomment %}
        <p class="my-3 text-danger" viewBox="0 0 16 16" data-bs-toggle="modal" data-bs-target="#deleteModal" style="cursor:pointer;display:inline-block;font-weight:700; font-size:12px;">
            <u>日報を削除する</u>
        </p>
    {% else %}
        <button class="btn btn-primary form-control" type="submit">登録</button>
    {% endif %}      
    </form>
    {% if object %}
        {% include 'nippo/nippo-delete.html' %}
    {% endif %}
</div>
{% endblock %}

【結果】

完成しました!!

その他修正箇所

「date」フィールドを追加したことにより、リストビューモデルクラスにも修正を加える必要があります

nippo-list

作成日付を表示するためのコードです

{{ obj.timestamp|date:"Y年n年j日" }}

{{ obj.date|date:"Y年n年j日" }}

と、「date」フィールドに直しましょう

models.py

現在、「timestamp」フィールドによって順番が入れ替えられてますが、これを作成日「date」フィールドでの順序に入れ替えます

【元の記述】

class NippoModelQuerySet(models.QuerySet):
    def search(self, user=None, query=None):
        ....
        return qs.order_by("-timestamp")

【変更後】

class NippoModelQuerySet(models.QuerySet):
    def search(self, user=None, query=None):
        ....
        return qs.order_by("-date")

まとめ

DateFieldを使用した場合、一緒にdatepickerも導入するととても便利です

「datepicker」導入の流れをまとめると、

  1. bootstrap4モジュールをインポート、設定する
  2. datepicker-plusモジュールをインポート、設定する
  3. フォームクラスで、インプットフィールドを指定する
  4. テンプレートで「jquery」「media」を読み込む

となります

ぜひ覚えて置きましょう!

さて次回は、リストビューですでに追加した検索機能に加えて、フィルター機能を追加していきます

今回追加した作成年月別公開済/ドラフトによりリスト表示を変更するために「django-filter」を使ったフィルター機能の追加方法をお伝えします

タイトルとURLをコピーしました