知識の枝

"All is well"

Python 残り時間を表示する方法

約187日前 2021年5月23日13:17
デジタル
Django Python HTML

改訂履歴


2021/5/23 投稿

1. 背景


Djangoを使った開発中に覚えたことを備忘録として残します。

今回はPythonで残り時間を作成し、Djangoのhtmlテンプレートに渡す方法を解説します。


2. ゴール


制限時間を計算し、Djangoのhtmlテンプレートで表示する。


3. はじめに


まずは使い方のイメージです。
このブログに設置されているアプリ「OneTimeStar」採用している制限時間機能で使われています。
(OneTimeStarはブログ上部の「Apps > OneTimeStar」から利用できます)

制限時間機能とは下の画面の右上に表示されている
「delete in 48 hour」の部分です。



このアプリではページを作成してから48時間後にページが自動で削除されるようになっています。

具体的には、
「現在の日時」が「作成した日時+48時間」を超えたらページを削除するという動作をサーバー側で定期的に実行しています。


さてここでユーザーが気にするのが「削除までの残り時間」だと思います。

あと何時間で削除されるのかページ上に表示されていたほうがありがたいですよね。
という訳で制限時間を表示してみましょう。


4. 有効期限を表示


4.1 - relativedelta


現在の時刻から●●時間後、●●日後の日付を取得したい。
そんな場合に使えるのが「relativedelta」です。

models.py - RandomURLモデル
delete_date = timezone.now() + relativedelta(hours=48)

will_delete_at = models.DateTimeField(verbose_name='will_be_deleted_at', default=delete_date)
上記のようにモデル自体に削除予定日時のフィールド(will_delete_at)を作り、モデルの作成日時から+48時間後の日時を入力します。

これでモデルの有効期限が決まりました。


4.2 - 残り時間


残り時間は、時間の引き算で算出します。

「有効期限」から「現在の日時」を引き算しましょう。
views.py
this_page = RandomURL.objects.filter(random_url=star_id)[0]

remaining_time_temp = this_page.will_delete_at - timezone.now()
時間の引き算を行っています。
これで「remaining_time_temp」には残り時間が保存されます。

これをそのままhtmlテンプレートに渡しても良いのですが、単位のフォーマット変換を行いたい場合もありますよね。
次項で単位を変更したいと思います。


4.3 - 表示方法


先ほどの引き算結果をそのまま表示すると下記のようになります。
print(remaining_time_temp)
1 day, 23:59:47.826451
細かすぎるので、●● hour と簡単に表示したいところです。

datetime型には「strftime()」という便利な変換メソッドがありますが、
上記の引き算を行った「remaining_time_temp」はdatetime型では無く、timedelta型というものに変化しています。
print(type(remaining_time_temp))
<class 'datetime.timedelta'>


このtimedelta型ではstrftime()メソッドを使用することができません。
したがって自力で計算する必要があります。


最終的にこんな形になります。
remaining_time = int(round(remaining_time_temp.total_seconds()/3600, 1))
total_second()メソッドでまず「秒」に直します。
次に3600秒で割って「時」に変換。
round関数で小数点以下を切り捨て。
int関数で整数型に変換します。

整数型にしているのはround関数を実行した時点で数値がfloat型だからです。
print(type(round(remaining_time_temp.total_seconds()/3600, 1)))
<class 'float'>
今回は●● hourと整数で表示したかったのでint()を使用しています。


あとはこの変数をhtmlテンプレートに渡したら完成です。
views.py
context = {
'remaining_time': remaining_time,
}

return render(request, template, context)
ここは通常通りですね。

無事ウェブページに残り時間が表示されました。



5. さいごに


次はリアルタイムに時間変化が確認できる方法を調べたいと思います。
今回紹介した方法はページの読み込み時にしか残り時間が更新されませんので。。。