Djangoでカレンダーを作るシリーズ
概要
Djangoで、カレンダアプリケーションを作成します。
例えば、月間カレンダー
週間カレンダー
各日のスケジュールも表示される、週間カレンダー
曜日、日付、スケジュールを1行に収めたり...
縦にするなども可能です。
スケジュール付きの月間カレンダー等もできます。
そして、これら全てを詰め込み、スケジュール作成ページもつけたカレンダー(Googleカレンダーのデフォルトページをイメージしました)
一括作成・更新機能付き月間カレンダー等もあります。
動作環境
Python: 3.6以上
Django: 2.0以上
初期設定
アプリケーション名をappとして進めていきます。
settings.py
設定ファイルに、appアプリケーションを定義します。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app', # カレンダーアプリ
]
urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('app.urls')),
]
models.py
スケジュールを管理するモデルとして、以下のようなものを予め定義しておきます。
import datetime
from django.db import models
from django.utils import timezone
class Schedule(models.Model):
"""スケジュール"""
summary = models.CharField('概要', max_length=50)
description = models.TextField('詳細な説明', blank=True)
start_time = models.TimeField('開始時間', default=datetime.time(7, 0, 0))
end_time = models.TimeField('終了時間', default=datetime.time(7, 0, 0))
date = models.DateField('日付')
created_at = models.DateTimeField('作成日', default=timezone.now)
def __str__(self):
return self.summary
mixins.py
mixins.py
というファイルをappディレクトリ内に作ります。ここに作るクラスは、カレンダー関連ビューを作るための部品です。views.py
に定義しても良いのですが、専用のmixins.py
のようなファイルを作っておくほうが管理しやすいですし、一般的です。
手始めに、次のようなMixinを定義しておきましょう。これは各Mixinの基底クラスになります。
import calendar
from collections import deque
class BaseCalendarMixin:
"""カレンダー関連Mixinの、基底クラス"""
first_weekday = 0 # 0は月曜から、1は火曜から。6なら日曜日からになります。お望みなら、継承したビューで指定してください。
week_names = ['月', '火', '水', '木', '金', '土', '日'] # これは、月曜日から書くことを想定します。['Mon', 'Tue'...
def setup(self):
"""内部カレンダーの設定処理
calendar.Calendarクラスの機能を利用するため、インスタンス化します。
Calendarクラスのmonthdatescalendarメソッドを利用していますが、デフォルトが月曜日からで、
火曜日から表示したい(first_weekday=1)、といったケースに対応するためのセットアップ処理です。
"""
self._calendar = calendar.Calendar(self.first_weekday)
def get_week_names(self):
"""first_weekday(最初に表示される曜日)にあわせて、week_namesをシフトする"""
week_names = deque(self.week_names)
week_names.rotate(-self.first_weekday) # リスト内の要素を右に1つずつ移動...なんてときは、dequeを使うと中々面白いです
return week_names
内部的に標準ライブラリ内のcalendar
モジュールを利用してカレンダーを作成しています。
デフォルトでは月曜日からカレンダーが始まりますが、火曜日から表示したいというケースも当然あるので、first_weekday
というクラス属性を定義しています。0はデフォルトの月曜日スタート、1なら火曜日...のようになります。
また、['月', '火', '水'...]
といった曜日のリストを柔軟に取得できるようにget_week_names()
も定義しています。first_weekday
を1にしたならば'['火', '水'...]'といった曜日リストを返してくれますし、week_names
属性を上書きすることで、['Mon', 'Tue']
のように曜日リストの表記も変更できます。
残りのMixinは、後で作っていきます。
base.html
Bootstrap4のスターターテンプレートを使っていきます。
<!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 rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<title>カレンダー</title>
</head>
<body>
<div class="container" mt-3>
{% block content %}{% endblock %}
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"
integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"
integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k"
crossorigin="anonymous"></script>
{% block extrajs %}{% endblock %}
</body>
</html>
後で追加のJavaScriptを少し書くので、{% block extrajs %}{% endblock %}
を定義しておきます。
月間カレンダー
まずは月間カレンダーです。次月、前月といった移動も勿論できます。
週間カレンダー
週間カレンダー
その週ごとに表示する機能も、よく見かけます。こちらも、前週・次週へ移動できます。
スケジュール付き週間カレンダー
スケジュール付き週間カレンダー
週間カレンダーは少しさみしいものでした。なので、拡張してスケジュールも表示できるものを作ります。
スケジュール付き月間カレンダー
スケジュールつき月間カレンダー
今度はスケジュール付きの、月間カレンダーを作ります。
スケジュール付き週間カレンダー+月間カレンダー+スケジュール登録フォーム
Djangoで、週間・月間カレンダー
Mixinを定義したおかげで、いくつかの機能を組み合わせるのも簡単です。
さらにgeneric.CreateViewも使い、スケジュール登録フォームもつけてみます。
一括作成・更新機能付き月間カレンダー
Djangoで、一括作成・更新機能付き月間カレンダー フォームセットを使い、月間カレンダーを表示しつつ各日のスケジュール登録・更新ができるようにしています。
完成品(Github)
Githubにソースコードがあります。
うごかしかた。
git clone https://github.com/naritotakizawa/django-simple-calendar
pip install django (pipenv install でも)
python manage.py migrate
python manage.py runserver