Django

【Django】ログイン判定機能の実装方法を実例付きで徹底解説

(最終更新月:2022年12月)

✔当記事はこのような方に向けて書かれています

「ログインしているかどうかってどうやったらわかるの?」

「ログインの有無によりHTML表示を変更したい!」

✔当記事でお伝えすること

  • アクセスしているユーザーのログイン状態を判定する方法
  • ログイン状態により、リンク先や表示内容を変更する方法
✔独学におすすめ

アクセスしているユーザーのログイン状況を判定する

ログイン状態を把握するためには、is_authenticated属性を使います。

is.authenticated属性は、ログイン時にはTrue、ログアウト時にはFalseを返してくれるからです。

テンプレート上で使用するのであれば、{{ }} で囲い、以下のようになります。

{{ request.user.is_authenticated }}

request.userについて詳しく知りたい方はこちらをどうぞ。

requestについて詳しく知りたい方はこちら。

ログイン状況によりHTMLコードを変更する

ログイン状況により、HTMLコードを変更するには、以下のようにおこないます。

  • is_authenticatedメソッドでログイン状況を判定
  • 判定したログイン状況により、if文を使って処理を記述

開発中の日報アプリを例に、ログイン/ログアウトの表示を切り替えていきます。

ログイン前

ログイン後

変更する箇所はこちらになります↓

is_authenticatedメソッドを使い、条件分岐をします

<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
      {% if request.user.is_authenticated %}
          <li><a class="dropdown-item" href="#">アカウント設定</a></li>
          <li><hr class="dropdown-divider"></li>
          <li><a class="dropdown-item" href={% url "account_logout" %}>ログアウト</a></li>
      {% else %}
          <li><a class="dropdown-item" href={% url "account_login" %}>ログイン</a></li>
          <li><hr class="dropdown-divider"></li>
          <li><a class="dropdown-item" href={% url "account_signup" %}>サインアップ</a></li>
      {% endif %}
</ul>

リンク先の変更

開発中の日報アプリの一覧ページでは、各日報へのリンクが貼られています。

ログイン状況により、以下の通り、リンク先を変更していきます。

  • ログインユーザーと日報作者が一致する場合は、編集ページへ
  • ログインユーザーと日報の作者が異なる場合は、詳細ページ(読み取り専用)へ

【request.user == nippo.user】

【request.user != nippo.user】

それぞれのレイアウトも多少変更していますが、

  1. nippo-list.html
  2. nippo-form.html
  3. nippo-detail.html

とそれぞれコードを見ていきましょう!

nippo-list.html

変更点は下記のとおりです

  • 「編集」リンクをなくしたこと
  • ログインユーザーによる条件分岐を追記
  • Cardに「max-width」などのスタイルを追加
{% extends "base.html" %}
{% block head_title %}日報アプリ一覧{% endblock %}
{% block content %}
<div class="container">
    {% if request.user.is_authenticated %}
        <div class="mt-3 d-flex justify-content-end">
            <a href={% url "nippo-create" %} class="btn btn-outline-primary float-end">
              <i class="bi bi-plus"></i>
            </a>
        </div>
    {% endif %}
    {% if object_list %}
        {% for obj in object_list %}
            <div class="card my-3">
                <div class="card-body">
                    <h5 class="card-title">
                      {% if obj.user == request.user %} 
                      <span class="float-end text-danger" data-bs-toggle="modal" data-bs-target="#deleteModal-{{obj.pk}}">
                          <i class="bi bi-trash-fill"></i>
                      </span>
                        <a href={% url 'nippo-update' obj.pk %}>
                      {% else %}
                        <a href={% url 'nippo-detail' obj.pk %}>
                      {% endif %}
                            {{ obj.title }}
                        </a>
                    </h5>
                    <p class="card-text">
                        {{ obj.content }}
                    </p>
                </div>
                <div class="card-footer">

                </div>
            </div>
            {% include "nippo/nippo-delete.html" with object=obj %}
        {% endfor %}
      {% else %}
        <div>日報が見つかりません</div>
      {% endif %}
</div>
{% endblock %}

nippo-form.html

変更点は下記のとおり。

  • pタグ「日報を削除する」で、Deleteモダルを表示
  • Deleteモダル(nippo-delete.html)をinclude
{% extends 'base.html' %}

{% block content %}
<div class="container my-3" style="max-width:700px;">
    
    <div class="text-center my-3">
    {% if object %}
        <h2>{{ object }}の編集</h2>
    {% else %}
        <h2>新しく日報を作成</h2>
    {% endif %}
    </div>
    
    <form method="POST"> {% csrf_token %}
    {{ form.as_p }}
    {% if object %}
        <button class="btn btn-primary form-control" type="submit">保存</button>
        <p class="my-3 text-danger" viewBox="0 0 16 16" data-bs-toggle="modal" data-bs-target="#deleteModal-{{object.pk}}" style="cursor:pointer;display:inline-block;font-weight:700; font-size:12px;">
            <u>日報を削除する</u>
        </p>
    {% else %}
        <button class="btn btn-primary form-control" type="submit">登録</button>
    {% endif %}      
    </form>
    {% if object %}
        {% include 'nippo/nippo-delete.html' %}
    {% endif %}
</div>
{% endblock %}

nippo-detail.html

変更点は下記のとおりです。

  • 編集、削除ボタンを非表示
  • カードフッターに「戻る」ボタンの追加
{% extends 'base.html' %}

{% block content %}
<div class="container">
    <div class="card mx-auto my-5 w-50" style="min-width:300px;">
        <div class="card-header">
            【作成日時】{{ object.timestamp }}
        </div>
        <div class="card-body pb-3">
            <h3 class="card-title mb-3 px-2" style="border-bottom:solid 1px #f4f4f4;">
                {{ object.title }}
            </h3>
            <p class="card-text my-3 px-5">{{ object.content }}</p>
        </div>
        <div class="card-footer">
            <a href={% url 'nippo-list' %} class="btn btn-danger btn-sm">戻る</a>
        </div>
    </div>
</div>
{% endblock %}

まとめ

ユーザーのログイン情報を得る方法はこの一文。

request.user.is_authenticated

条件分岐を活用し意図した表示やリンク先になるよう記述すれば、あなたの意図したとおりの動線が作れるので、参考にしてください。

次回の日報アプリ開発チュートリアルでは、ユーザーモデルクラスを拡張する方法、OneToOneFieldについて解説していきます。