1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

DjangoでiCalendar(.ics)ファイルをダウンロードする方法

Last updated at Posted at 2022-02-03

はじめに

こんにちは、reimeiです。
先日Djangoで開発しているwebアプリケーションにてDBに保存しているスケージュールをiCalendarファイルに書き出して返す処理を実装しようとした際、つまづいたので共有しようと思います。

解決策

▼とりあえず、必要なライブラリをインストール

$ pip3 install ics

▼実装例

from ics import Calendar, Event
import arrow
import os
from django.http import HttpResponse

def download_icalendar_file(request):
    calendar = Calendar()
    event = Event()
    event.name = "飲み会"
    event.begin = arrow.get("2022-2-3 20:00:00", "YYYY-MM-DD HH:mm:ss") \
            .replace(tzinfo='Asia/Tokyo')
    event.end = arrow.get("2022-2-3 23:30:00", "YYYY-MM-DD HH:mm:ss") \
            .replace(tzinfo="Asia/Tokyo")
    calendar.events.add(event)

    with open('calendar.ics', 'w') as f:
        f.write(str(calendar))
    with open('calendar.ics', 'rb') as f:
        response = HttpResponse(f.read(), content_type="text/calendar")
        response['Content-Disposition'] =\
            'inline; filename=' + os.path.basename('schedule.ics')
        os.remove('schedule.ics')
        return response

解説

必要なライブラリをインポートしている。

from ics import Calendar, Event
import arrow
import os
from django.http import HttpResponse

カレンダーやイベント情報の設定を行っている。 `event = Event()` 以下を繰り返し実行すると複数のイベント情報を持つカレンダーを作成することができる。 時間は何もせずに設定すると世界標準の時間になってしまうので時差を計算するか以下のようにタイムゾーンを変更するなどの処理を行う必要があるので注意。
calendar = Calendar()
event = Event()
event.name = "飲み会"
event.begin = arrow.get("2022-2-3 20:00:00", "YYYY-MM-DD HH:mm:ss") \
        .replace(tzinfo='Asia/Tokyo')
event.end = arrow.get("2022-2-3 23:30:00", "YYYY-MM-DD HH:mm:ss") \
        .replace(tzinfo="Asia/Tokyo")
calendar.events.add(event)

calendar.icsという名前のファイルにカレンダー情報を書き込んでいる。
with open('calendar.ics', 'w') as f:
    f.write(str(calendar))

カレンダーファイルをクライアントに返すためのレスポンスの設定を行っている。 また、作成したschedule.icsが残り続けると邪魔なので削除も行っている。 ▼メディアタイプには `text/calendar` という形式があるらしい(今回初めて知った)

with open('calendar.ics', 'rb') as f:
    response = HttpResponse(f.read(), content_type="text/calendar")
    response['Content-Disposition'] =\
        'inline; filename=' + os.path.basename('schedule.ics')
    os.remove('schedule.ics')
    return response

あとはurls.pyでリンクを設定したり、そのリンクをtemplateに貼り付ければ完成!

最後に

今回DjangoでiCalendarファイルをダウンロードする機能を実装していた際、躓いたが日本語の記事が見つからなかったのでまとめてみました。
また、今回紹介した解決方法よりも良い方法をご存知の方は教えていただきたいです!
(特にレスポンスの設定をいじっているあたり)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?