Djangoで週間カレンダー

2018-10-07 / PythonDjangoBootstrap4

概要

Djangoで、カレンダーを作るシリーズの1つです。週間カレンダーを作成していきます。こちらもよく使う機能で、便利です。月間カレンダーに比べると幅を取らないのが特徴です。空いたスペースに、色々な機能をつけることもできるでしょう(その日のスケジュール表示など)。

次のようなものが作れます。 週間カレンダー

mixins.py

週間カレンダー用のMixinクラスを定義します。

class WeekCalendarMixin(BaseCalendarMixin):
    """週間カレンダーの機能を提供するMixin"""

    def get_week_days(self):
        """その週の日を全て返す"""
        month = self.kwargs.get('month')
        year = self.kwargs.get('year')
        day = self.kwargs.get('day')
        if month and year and day:
            date = datetime.date(year=int(year), month=int(month), day=int(day))
        else:
            date = datetime.date.today()

        for week in self._calendar.monthdatescalendar(date.year, date.month):
            if date in week:  # 週ごとに取り出され、中身は全てdatetime.date型。該当の日が含まれていれば、それが今回表示すべき週です
                return week

    def get_week_calendar(self):
        """週間カレンダー情報の入った辞書を返す"""
        self.setup_calendar()
        days = self.get_week_days()
        first = days[0]
        last = days[-1]
        calendar_data = {
            'now': datetime.date.today(),
            'week_days': days,
            'week_previous': first - datetime.timedelta(days=7),
            'week_next': first + datetime.timedelta(days=7),
            'week_names': self.get_week_names(),
            'week_first': first,
            'week_last': last,
        }
        return calendar_data

一番重要なのはget_week_calendar()メソッドで、これが週間カレンダー構築に必要なものが詰まった辞書を返します。 辞書の各キーと返すものの説明します。

now

現在の日付で、datetime.date型のオブジェクトを返します。これを使うと、その日が今日なら色をつける...なんてことができます。

week_days

これは、その週の全ての日を返しています。なので、7つのdatetime.dateオブジェクトが返されます。 月をまたいている日付が出ることもありますが、正しく跨いだ月でのdatetime.date型になっています、安心です。

week_first

一週間の、最初の日です(datetime.date型)

week_last

一週間の、最後の日です(datetime.date型)

week_previous

前の週です。週の始まりを示すfirstを基準に、7日引いているだけです。(datetime.date型)

week_next

次の週です。週の始まりを示すfirstを基準に、7日足しているだけです(datetime.date型)

nowとweek_namesは、月間カレンダーと同様です。

urls.py

/weekと、/week/2018/5/5 のようなURLで、週間カレンダーが表示されます。 year、month、dayといった名前は固定です。年と月と日さえわかればその週を取り出せるので、中なか便利です。

    # 追加
    path('week/', views.WeekCalendar.as_view(), name='week'),
    path('week/<int:year>/<int:month>/<int:day>/', views.WeekCalendar.as_view(), name='week'),

views.py

WeekCalendarMixinを継承するだけです。MonthCalendarMixinと使い方は同じですね。

class WeekCalendar(mixins.WeekCalendarMixin, generic.TemplateView):
    """週間カレンダーを表示するビュー"""
    template_name = 'app/week.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        calendar_context = self.get_week_calendar()
        context.update(calendar_context)
        return context

week.html

週間カレンダーのテンプレートです。month.htmlと、流れは同じです。

{% extends 'app/base.html' %}
{% block content %}

    <a href="{% url 'app:week' week_previous.year week_previous.month  week_previous.day %}">前週</a>
    {{ week_first | date:"Y年m月d日" }}〜{{ week_last | date:"Y年m月d日" }}
    <a href="{% url 'app:week' week_next.year week_next.month  week_next.day %}">次週</a>

    <table class="table">
        <thead>
        <tr>
            {% for w in week_names %}
                <th>{{ w }}</th>
            {% endfor %}
        </tr>
        </thead>
        <tbody>
        <tr>
            {% for day in week_days %}
                {% if now == day %}
                    <td class="table-success">
                        {% else %}
                    <td>
                {% endif %}
            {% if week_first.month != day.month %}
                {{ day | date:"m/d" }}
            {% else %}
                {{ day.day }}
            {% endif %}
            </td>
            {% endfor %}
        </tr>
        </tbody>
    </table>
{% endblock %}

この記事の関連記事

Djangoでカレンダーを作るシリーズ

2018-10-07 / PythonDjangoBootstrap4シリーズ・まとめ

- Djangoで、月間カレンダーや週間カレンダー、それぞれにスケジュール表示機能がついたもの、スケジュール登録フォームがついたもの等、様々なカレンダーを作成していきます。

コメント欄

記事にコメントする

まだコメントはありません。