やりたいこと
Djangoで某サークルの機材予約をWebからできるようにしようとしていて、
過去の予約データを編集したり、削除できないようにするために
現在時刻より前の予定の編集ボタンや削除ボタンを非表示にしたい。
そのための条件分岐をtemplatesに記述しようとして苦戦。
context = {
'band_name' : band_name,
'schedules' : Schedule.objects.all(),
'target_date' : datetime.datetime.now()
}
return render(request, 'xxx.html', context)
{% schedule in schedules %}
{% if schedule.target_date > target_date %}
ボタン表示
{% endif %}
{% endfor %}
変数(今日の日付)とモデルをtemplatesに渡して
schedulesのループの中で日付で条件分岐をしてボタンを表示・非表示を制御したい
しかし、うまく条件分岐できない。
単純に
{% if True %}
ではうまく条件分岐ができていたので、viewで予め判定して、モデルのidと判定結果(Bool)を辞書として
templatesに渡して制御しようとした
my_dic = {}
target_date = datetime.datetime.now()
for schedule in schedules:
if target_date < schedule.target_date:
my_dic[schedule.id] = True
else:
my_dic[schedule.id] = False
context = {
'schedules' : Schedule.objects.all(),
'my_dic' : my_dic,
}
return render(request, 'xxx.html', context)
{% schedule in schedules %}
{% if my_dic[schedule.target_date] %}
ボタン表示
{% endif %}
{% endfor %}
しかし、これもうまくいかない。
templates内で辞書の展開は
my_dic.id
でidにキーを指定すれば展開ができるが、この「.id」の部分にschedulesのループ内のschedule.idを渡したいが
これもうまくいかない。
withタグを使って変数を代入してもうまくいかない。
{% with target_id = schedule.id %}
{% if my_dic[schedule.target_id] %}
これもうまくいかない。
{% if my_dic.schedule.id %}
{% if my_dic[schedule.id] %}
これらはもちろんダメだった。
###解決策
モデルに直接ニョキっとメソッドを生やした。
class Schedule(models.Model):
# カラムの定義 ・・・
target_date = models.DateField(default=timezone.now, verbose_name=‘予約日‘)
def is_available(self):
current_day = timezone.datetime.today()
return current_day < self.active_date
{% schedule in schedules %}
{% if schedule.is_available %}
ボタン表示
{% endif %}
{% endfor %}
Done.
このメソッドを使えばURLでの直接アクセスに対してもredirectできそう。
やりたいことに書いたようなコーディングでうまくいかないものなのか、、、
もちろんtemplatesでロジックはなるべく書かない方がよいが、
辞書の参照などのちょっとした操作はうまく働いて欲しかった。
他にもtemplates filterを自分で作ってしまうなどの解決策は見つけたが、
今のところはこのやり方が一番綺麗だと思う。
以上です。
P.S.
ちゃんゆーさん(@chanyou0311)にご教授頂きました。感謝です。