1.10 Bootstrap 4.0+Django-bootstrap-datepicker-plusの利用(DJango 2.2.7) [Django]
今までDjango管理画面のCSSやカレンダーを利用していたが、
見栄えをBootstrap 4.0 に変更するために、
新たにPycharmProjectsd4 をこしらえました。
DBも、SQLite から MySQL 8.0.18に変更。
1.今回のポイント
(1) 日付入力(カレンダー)があるため、datepicker_plus を使いします。
(2) BootstrapのCDNは利用しません。
パフォーマンスとか考慮するならCDNの方が良いようですが、
仕事の本番環境を考慮し、ローカルからアクセスするようにしました。
A. 本番環境がWebアクセス出来ない環境の場合でも耐えられるよう
B. 何かしらの事由でCDNサイトが利用出来なくなっても耐えられるよう
C. 社内システムのためそんなにアクセスが爆発的ではないため、
さほどパフォーマンス考慮が不要なため
ちなみにダウンロードして配置しているのは以下です。
bootstrap-4.3.1-dist
bootstrap-datepicker-1.9.0-dist
moment.js
popper.js
tempusdominus-bootstrap-4
fontawesome-free-5.11.2-desktop(今回のには関係ない)
fontawesome-free-5.11.2-web(今回のには関係ない)
以下フォルダに無造作に配置
C:\PycharmProjects4\Recruitment\applicantctl\static\applicantctl
2.作業
(1) django-bootstrap-datepicker-plusのインストール
venv環境にて下記コマンドを実行
pip install django-bootstrap-datepicker-plus
(2) settings.pyの変更
'bootstrap_datepicker_plus',を追加(11行目)
(3) Baseテンプレートファイルの変更
Bootstrap用のURLをbase.htmlへ設定。
CDNは使わないので、
{% load bootstrap4 %},{% bootstrap_css %},{% bootstrap_javascript jquery='full' %}
は、きっと利用出来ないのでベタ書き。(8~11行目、48~49行目)
Base.html
(4) カレンダー利用画面用のテンプレート
(Baseテンプレートを継承)
base_datetimepicker.html
(5) 追加画面用のhtmlテンプレート
1行目に、 base_datetimepicker.html を指定
js、cssをリンクするだけで特にhtmlの内容を気にする必要は無い
upd.html
(6) formクラスの変更
追加日付項目という名前でDatePickerInputで年月表示のしカレンダーが表示されるように指定(14-24行目)
・日付フォーマットを、"%Y/%m"として指定しています。(18行目)
・optionで、ja(日本)と、months(年月表示)を指定している。(20-21行目)
(7) modelFormクラスの変更
・Metaクラス内で、年月日表示のしカレンダーが表示されるように指定(50-54行目)
・日付フォーマットを、"%Y/%m/%d"として指定しています。(51行目)
・optionで、ja(日本)を指定している。(52-54行目)
※当然ですが日付やオプションの指定方法は、Django-bootstrap-datepicker-plusでの指定方法となります。
Bootstrap DatePickerやDateTimePickerの指定方法とは異なります。
forms.py
蛇足ですが、formatを %y/%m と年月にするとカレンダはそのように動作しましたが、
is_validで日付フォーマットではないとエラーになります。(まーとうぜんですね)
3.確認
サーバを起動。
画面レイアウトが少々ダサイのは、おいておいて、
とりあえず bootstrapとして表示出来た。
年月日バージョン
年月バージョン
ページング機能のレイアウトも以前より良い感じです。
ページング機能の掲載は別ページで。
中身を確認
実際に出力されたHTMLは下記内容となった。
応募日( ModelForm側 )の出力されたHTML
2行目のパラメータがエンコードされていて見づらいのでデコードすると下記のようになります。
ここでパラメータを指定していました。
追加項目( From側 )の出力されたHTML
こちらもデコードすると下記のようになります。ここでパラメータを指定していました。
良く見ると data-target で指定しているのが両者ともに"#datetimepicker1"を指定している。
他のDatePickerだと、JavaScriptで下記のような記載が必要なのだが、
Django-bootstrap-datepicker-plusでは不要のようです。
しかも同じ名前でもうまく動くというのが少々不思議ですが・・。
全ソースは、こちらに保存
https://github.com/MakotoPlus/PycharmProjects4
補足
DatePickerは、いろんな種類があるようです。
https://qiita.com/knt45/items/6d74f6785cd4547ae53b
自分は、 DateTimePicker と Bootstrap DatePicker が同じものだと勘違いしていました・・。
https://ascii.jp/elem/000/000/883/883101/
ちょっと認識間違えでハマりました・・。
Bootstrap DatePicker は、 Bootstrapで用意されているDatePicker であって、
DateTimePickerは、Jquery pluginを利用したカレンダのようである。
そして、Django用Datepckerライブラリが、django-bootstrap-datepicker-plusです。
こちら、datepickerと言いながら、利用時は、datetimepckerと「time」を付けるので
混乱する理由となった(イイワケ)
Bootstrap DatePicker
https://uxsolutions.github.io/bootstrap-datepicker/?markup=input&format=&weekStart=&startDate=&endDate=&startView=0&minViewMode=0&maxViewMode=4&todayBtn=false&clearBtn=false&language=en&orientation=auto&multidate=&multidateSeparator=&keyboardNavigation=on&forceParse=on#sandbox
DateTimePicker
https://xdsoft.net/jqplugins/datetimepicker/
Django-bootstrap-datepicker-plus
https://django-bootstrap-datepicker-plus.readthedocs.io/en/latest/Walkthrough.html
Django-bootstrap-datepicker-plusでの参考サイトは下記
https://pisuke-code.com/bootstrap-how-to-show-datepicker/
https://intellectual-curiosity.tokyo/2018/11/09/django%E3%81%A7datepicker%EF%BC%88%E3%82%AB%E3%83%AC%E3%83%B3%E3%83%80%E3%83%BC%E3%81%AB%E3%82%88%E3%82%8B%E6%97%A5%E6%99%82%E5%85%A5%E5%8A%9B%EF%BC%89%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B/
見栄えをBootstrap 4.0 に変更するために、
新たにPycharmProjectsd4 をこしらえました。
DBも、SQLite から MySQL 8.0.18に変更。
1.今回のポイント
(1) 日付入力(カレンダー)があるため、datepicker_plus を使いします。
(2) BootstrapのCDNは利用しません。
パフォーマンスとか考慮するならCDNの方が良いようですが、
仕事の本番環境を考慮し、ローカルからアクセスするようにしました。
A. 本番環境がWebアクセス出来ない環境の場合でも耐えられるよう
B. 何かしらの事由でCDNサイトが利用出来なくなっても耐えられるよう
C. 社内システムのためそんなにアクセスが爆発的ではないため、
さほどパフォーマンス考慮が不要なため
ちなみにダウンロードして配置しているのは以下です。
bootstrap-4.3.1-dist
bootstrap-datepicker-1.9.0-dist
moment.js
popper.js
tempusdominus-bootstrap-4
fontawesome-free-5.11.2-desktop(今回のには関係ない)
fontawesome-free-5.11.2-web(今回のには関係ない)
以下フォルダに無造作に配置
C:\PycharmProjects4\Recruitment\applicantctl\static\applicantctl
2.作業
(1) django-bootstrap-datepicker-plusのインストール
venv環境にて下記コマンドを実行
pip install django-bootstrap-datepicker-plus
(2) settings.pyの変更
'bootstrap_datepicker_plus',を追加(11行目)
# Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'accounts.apps.AccountsConfig', 'applicantctl', 'bootstrap_datepicker_plus', 'mytest', ]
(3) Baseテンプレートファイルの変更
Bootstrap用のURLをbase.htmlへ設定。
CDNは使わないので、
{% load bootstrap4 %},{% bootstrap_css %},{% bootstrap_javascript jquery='full' %}
は、きっと利用出来ないのでベタ書き。(8~11行目、48~49行目)
Base.html
{% load static %} <!doctype html> <html lang="ja"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link href="{% static 'applicantctl/bootstrap-4.3.1-dist/css/bootstrap.min.css' %}" rel="stylesheet"> <!-- Bootstrap CSS Fotter--> <link href="{% static 'applicantctl/bootstrap-4.3.1-dist/sticky-footer-navbar.css' %}" rel="stylesheet"> <title>applicantctl-django</title> {% block head_meta %}{% endblock %} </head> <style> html { font-size: 12px; } </style> <body>{% block navi %} <nav class="navbar navbar-expand-sm sticky-top navbar-dark bg-primary mt-3 mb-3"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav4" aria-controls="navbarNav4" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <a class="navbar-brand" href="{% url 'applicantctl:index' %}">応募者管理システム(applicantctl-django)</a> <div class="collapse navbar-collapse justify-content-end"> <ul class="navbar-nav"> <li class="nav-item active"> {% if user.is_authenticated %} <a class="nav-link" href="{% url 'logout' %}" class="logout">Logout({{ user.first_name}} {{ user.last_name}})</a> {% else %} <a class="nav-link" href="{% url 'accounts:signup' %}" class="signup">Sign up</a></li> <a class="nav-link" href="{% url 'login' %}" class="login">Login</a> {% endif %} </li> </ul> </div> </nav> {% endblock %} {% block content %}{% endblock %} {% block fotter %} <footer class="footer mt-auto py-3 text-right"> <span class="text-right">Copyright 2019 Makoto Inc. All Rights Reserved.</span> </footer> <!-- jQuery first, then Popper.js, then Bootstrap JS --> {% endblock %} <script src="{% static 'applicantctl/bootstrap-4.3.1-dist/js/jquery-3.4.1.min.js' %}"></script> <script src="{% static 'applicantctl/bootstrap-4.3.1-dist/js/bootstrap.bundle.min.js' %}"></script> </body> </html>
(4) カレンダー利用画面用のテンプレート
(Baseテンプレートを継承)
base_datetimepicker.html
{% extends 'base.html' %} {% load static %} {% block head_meta %} <script src="{% static 'applicantctl/bootstrap-4.3.1-dist/js/jquery-3.4.1.min.js' %}"></script> <script src="{% static 'applicantctl/popper.js/popper.min.js' %}"></script> <script src="{% static 'applicantctl/bootstrap-4.3.1-dist/js/bootstrap.min.js' %}"></script> <!--bootstrap css--> <!--local datapicker--> <!--form.media--> <link href="{% static 'applicantctl/bootstrap-datetimepicker_4.17.47/css/bootstrap-datetimepicker.css' %}" type="text/css" media="all" rel="stylesheet"> <link href="/static/bootstrap_datepicker_plus/css/datepicker-widget.css" type="text/css" media="all" rel="stylesheet"> <script type="text/javascript" src="{% static 'applicantctl/moment-2.9.0/moment-with-locales.min.js' %}"></script> <script type="text/javascript" src="{% static 'applicantctl/bootstrap-datetimepicker.min.js_4.17.47/cdnjs/bootstrap-datetimepicker.min.js' %}"></script> <script type="text/javascript" src="/static/bootstrap_datepicker_plus/js/datepicker-widget.js"></script> {% endblock %} {% block content %}{% endblock %}
(5) 追加画面用のhtmlテンプレート
1行目に、 base_datetimepicker.html を指定
js、cssをリンクするだけで特にhtmlの内容を気にする必要は無い
upd.html
{% extends "base_datetimepicker.html" %} {% block content %} </br> {% if errmsg %} <p class="alert alert-danger">{{ errmsg }}</p> {%endif%} <!-- {% for field, errors in form.errors.items %} {% for error in errors %} <p class="alert alert-danger">{{ error }}</p> {% endfor %} {% endfor %} --> </br> <form name="form" method="post" action="{% url 'applicantctl:upd' key_applicant %}"> {% csrf_token %} <div class="container"> {{ form.as_p }} </div> </br> <div class="row"> <div class="col-md-2"> </div> <div class="col-md-2"> <input type="button" class="btn btn-block btn-primary" OnClick="ButtonClick('1');" value="更新" > </div> <div class="col-md-2"> <input type="button" class="btn btn-block btn-primary" OnClick="ButtonClick('2');" value="削除" > </div> <div class="col-md-6"> </div> </div> </br> </div> </form> </br> <script> function ButtonClick(param){ if (param == '2' ){ document.form.action ="{% url 'applicantctl:delete' key_applicant %}"; var result = confirm('削除してよろしいですか?' ); if (result){ document.form.submit(); } }else{ document.form.submit(); } } </script> {% endblock%}
(6) formクラスの変更
追加日付項目という名前でDatePickerInputで年月表示のしカレンダーが表示されるように指定(14-24行目)
・日付フォーマットを、"%Y/%m"として指定しています。(18行目)
・optionで、ja(日本)と、months(年月表示)を指定している。(20-21行目)
(7) modelFormクラスの変更
・Metaクラス内で、年月日表示のしカレンダーが表示されるように指定(50-54行目)
・日付フォーマットを、"%Y/%m/%d"として指定しています。(51行目)
・optionで、ja(日本)を指定している。(52-54行目)
※当然ですが日付やオプションの指定方法は、Django-bootstrap-datepicker-plusでの指定方法となります。
Bootstrap DatePickerやDateTimePickerの指定方法とは異なります。
forms.py
import bootstrap_datepicker_plus as datetimepicker ######################################### # 応募者登録フォーム class T_Applicant_infoForm(forms.ModelForm): # #追加の場合はこれでOK #date_field = forms.DateField( # widget=datetimepicker.DatePickerInput(format='%Y/%m/%d',) # , label='追加日付項目' #) date_field = forms.DateField( label='追加日付項目', required = False, widget=datetimepicker.DatePickerInput( format='%Y/%m', options={ 'locale':'ja', 'viewMode' : 'months' } ) ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) for field in self.fields.values(): field.widget.attrs['class'] = 'form-control' #self.fields["u_date"].required = False self.fields['u_date'].widget = forms.HiddenInput() class Meta: model = T_Applicant_info fields = ( 'applicant_date', 'key_appl_route', 'applicant_no', 'applicant_name_text', 'key_history_kbn', 'u_date', ) error_messages = { 'applicant_no' : { 'required': '必須です!' }, 'applicant_name_text' : { 'required': '必須です!' } } widgets = { 'applicant_date':datetimepicker.DatePickerInput( format='%Y/%m/%d', options={ 'locale':'ja', } ), }
蛇足ですが、formatを %y/%m と年月にするとカレンダはそのように動作しましたが、
is_validで日付フォーマットではないとエラーになります。(まーとうぜんですね)
3.確認
サーバを起動。
画面レイアウトが少々ダサイのは、おいておいて、
とりあえず bootstrapとして表示出来た。
年月日バージョン
年月バージョン
ページング機能のレイアウトも以前より良い感じです。
ページング機能の掲載は別ページで。
中身を確認
実際に出力されたHTMLは下記内容となった。
応募日( ModelForm側 )の出力されたHTML
<p><label for="id_applicant_date">応募日:</label> <div class="input-group date"> <input type="text" name="applicant_date" value="2019/10/31" class="form-control" required id="id_applicant_date" dp_config="{"id": "dp_2", "picker_type": "DATE", "linked_to": null, "options": {"showClose": true, "showClear": true, "showTodayButton": true, "locale": "ja", "format": "YYYY/MM/DD"}}"/> <div class="input-group-addon input-group-append" data-target="#datetimepicker1" data-toggle="datetimepickerv"> <div class="input-group-text"><i class="glyphicon glyphicon-calendar"></i></div> </div>
2行目のパラメータがエンコードされていて見づらいのでデコードすると下記のようになります。
ここでパラメータを指定していました。
<p><label for="id_applicant_date">応募日:</label> <div class="input-group date"> <input type="text" name="applicant_date" value="2019/10/31" class="form-control" required id="id_applicant_date" dp_config="{"id": "dp_2", "picker_type": "DATE", "linked_to": null, "options": {"showClose": true, "showClear": true, "showTodayButton": true, "locale": "ja", "format": "YYYY/MM/DD"}}"/> <div class="input-group-addon input-group-append" data-target="#datetimepicker1" data-toggle="datetimepickerv"> <div class="input-group-text"><i class="glyphicon glyphicon-calendar"></i></div> </div>
追加項目( From側 )の出力されたHTML
<p><label for="id_date_field">追加日付項目:</label> <div class="input-group date"> <input type="text" name="date_field" class="form-control" id="id_date_field" dp_config="{"id": "dp_1", "picker_type": "DATE", "linked_to": null, "options": {"showClose": true, "showClear": true, "showTodayButton": true, "locale": "ja", "viewMode": "months", "format": "YYYY/MM"}}"/> <div class="input-group-addon input-group-append" data-target="#datetimepicker1" data-toggle="datetimepickerv"> <div class="input-group-text"><i class="glyphicon glyphicon-calendar"></i></div> </div>
こちらもデコードすると下記のようになります。ここでパラメータを指定していました。
<p><label for="id_date_field">追加日付項目:</label> <div class="input-group date"> <input type="text" name="date_field" class="form-control" id="id_date_field" dp_config="{"id": "dp_1", "picker_type": "DATE", "linked_to": null, "options": {"showClose": true, "showClear": true, "showTodayButton": true, "locale": "ja", "viewMode": "months", "format": "YYYY/MM"}}"/> <div class="input-group-addon input-group-append" data-target="#datetimepicker1" data-toggle="datetimepickerv"> <div class="input-group-text"><i class="glyphicon glyphicon-calendar"></i></div> </div>
良く見ると data-target で指定しているのが両者ともに"#datetimepicker1"を指定している。
他のDatePickerだと、JavaScriptで下記のような記載が必要なのだが、
Django-bootstrap-datepicker-plusでは不要のようです。
しかも同じ名前でもうまく動くというのが少々不思議ですが・・。
<script type="text/javascript"> $('#datetimepicker1').datepicker(); </script>
全ソースは、こちらに保存
https://github.com/MakotoPlus/PycharmProjects4
補足
DatePickerは、いろんな種類があるようです。
https://qiita.com/knt45/items/6d74f6785cd4547ae53b
自分は、 DateTimePicker と Bootstrap DatePicker が同じものだと勘違いしていました・・。
https://ascii.jp/elem/000/000/883/883101/
ちょっと認識間違えでハマりました・・。
Bootstrap DatePicker は、 Bootstrapで用意されているDatePicker であって、
DateTimePickerは、Jquery pluginを利用したカレンダのようである。
そして、Django用Datepckerライブラリが、django-bootstrap-datepicker-plusです。
こちら、datepickerと言いながら、利用時は、datetimepckerと「time」を付けるので
混乱する理由となった(イイワケ)
Bootstrap DatePicker
https://uxsolutions.github.io/bootstrap-datepicker/?markup=input&format=&weekStart=&startDate=&endDate=&startView=0&minViewMode=0&maxViewMode=4&todayBtn=false&clearBtn=false&language=en&orientation=auto&multidate=&multidateSeparator=&keyboardNavigation=on&forceParse=on#sandbox
DateTimePicker
https://xdsoft.net/jqplugins/datetimepicker/
Django-bootstrap-datepicker-plus
https://django-bootstrap-datepicker-plus.readthedocs.io/en/latest/Walkthrough.html
Django-bootstrap-datepicker-plusでの参考サイトは下記
https://pisuke-code.com/bootstrap-how-to-show-datepicker/
https://intellectual-curiosity.tokyo/2018/11/09/django%E3%81%A7datepicker%EF%BC%88%E3%82%AB%E3%83%AC%E3%83%B3%E3%83%80%E3%83%BC%E3%81%AB%E3%82%88%E3%82%8B%E6%97%A5%E6%99%82%E5%85%A5%E5%8A%9B%EF%BC%89%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B/
- ショップ: 楽天ブックス
- 価格: 523 円
コメント 0