LoginSignup
2
3

More than 3 years have passed since last update.

DjangoのTemplatesでの条件分岐に苦戦した。

Last updated at Posted at 2019-12-02

やりたいこと

Djangoで某サークルの機材予約をWebからできるようにしようとしていて、
過去の予約データを編集したり、削除できないようにするために
現在時刻より前の予定の編集ボタンや削除ボタンを非表示にしたい。

そのための条件分岐をtemplatesに記述しようとして苦戦。

views.py
context = {
    'band_name' : band_name,
    'schedules' : Schedule.objects.all(),
    'target_date' : datetime.datetime.now()
}
return render(request, 'xxx.html', context)
xxx.html
{% schedule in schedules %}
  {% if schedule.target_date > target_date %}
    ボタン表示
  {% endif %}
{% endfor %}

変数(今日の日付)とモデルをtemplatesに渡して
schedulesのループの中で日付で条件分岐をしてボタンを表示・非表示を制御したい

しかし、うまく条件分岐できない。
単純に
{% if True %}
ではうまく条件分岐ができていたので、viewで予め判定して、モデルのidと判定結果(Bool)を辞書として
templatesに渡して制御しようとした

views.py
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)
xxx.html
{% 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] %}
これらはもちろんダメだった。

解決策

モデルに直接ニョキっとメソッドを生やした。

models.py
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
xxx.html
{% schedule in schedules %}
  {% if schedule.is_available %}
    ボタン表示
  {% endif %}
{% endfor %}

Done.

このメソッドを使えばURLでの直接アクセスに対してもredirectできそう。

やりたいことに書いたようなコーディングでうまくいかないものなのか、、、
もちろんtemplatesでロジックはなるべく書かない方がよいが、
辞書の参照などのちょっとした操作はうまく働いて欲しかった。

他にもtemplates filterを自分で作ってしまうなどの解決策は見つけたが、
今のところはこのやり方が一番綺麗だと思う。

以上です。

P.S.
ちゃんゆーさん(@chanyou0311)にご教授頂きました。感謝です。

2
3
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
2
3