この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:4
ページ更新者:T
更新日時:2026-06-11 07:10:02

タイトル: テンプレート側のログイン判定
SEOタイトル: Django テンプレートでログイン判定する方法(is_authenticated / is_staff / グループ判定)

この記事の要点
  • {% if user.is_authenticated %} でログイン済か判定するのが基本
  • request をテンプレートに渡すのは django.template.context_processors.request、ユーザーは auth プロセッサ
  • 管理者判定: user.is_staff / スーパーユーザー: user.is_superuser
  • グループ判定: {% if user.groups.all|length > 0 %} または カスタムテンプレートタグ
  • ログイン強制はテンプレート側ではなく view 側の @login_required デコレータで
  • JSON API では request.user.is_authenticated を view で判定し、403 を返す

基本: is_authenticated

Django で「ログインしているか」を判定する最もシンプルな方法:

{# templates/base.html #}
<nav>
    {% if user.is_authenticated %}
        <span>こんにちは {{ user.username }} さん</span>
        <a href="{% url 'logout' %}">ログアウト</a>
    {% else %}
        <a href="{% url 'login' %}">ログイン</a>
        <a href="{% url 'signup' %}">新規登録</a>
    {% endif %}
</nav>

user 変数はテンプレート内で自動的に使えます(後述の context processor が設定されている場合)。

context_processors の確認

テンプレートから userrequest を参照できるのは、Django のauth コンテキストプロセッサが有効だからです:

# settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',     # ← request 変数
                'django.contrib.auth.context_processors.auth',     # ← user / perms 変数
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

auth プロセッサが入っていれば、すべてのテンプレートで {{ user }}{{ perms }} が使えます。

権限別の表示制御

{% if user.is_authenticated %}
    {# 一般会員向け #}
    <a href="{% url 'mypage' %}">マイページ</a>

    {% if user.is_staff %}
        {# スタッフ向け(管理画面アクセス可) #}
        <a href="{% url 'admin:index' %}">管理画面</a>
    {% endif %}

    {% if user.is_superuser %}
        {# スーパーユーザー専用 #}
        <a href="{% url 'system_settings' %}">システム設定</a>
    {% endif %}

    {% if user.email_verified %}
        {# 自前で追加した属性も普通に使える #}
        <span class="badge">認証済</span>
    {% endif %}
{% else %}
    <a href="{% url 'login' %}">ログイン</a>
{% endif %}

パーミッション判定: {% if perms.app.action %}

Django の django.contrib.auth のパーミッションシステムに沿うなら:

{# polls アプリの change_poll 権限を持っているか #}
{% if perms.polls.change_poll %}
    <a href="{% url 'polls:edit' poll.id %}">編集</a>
{% endif %}

{# 複数 #}
{% if perms.polls.add_poll and perms.polls.delete_poll %}
    <button>追加 & 削除</button>
{% endif %}

グループ判定

「特定のグループに所属しているか」をテンプレートで判定したい場合:

# myapp/templatetags/auth_extras.py
from django import template

register = template.Library()

@register.filter(name='has_group')
def has_group(user, group_name):
    return user.groups.filter(name=group_name).exists()
{% load auth_extras %}

{% if user|has_group:"editors" %}
    <a href="{% url 'cms:editor' %}">編集者ダッシュボード</a>
{% endif %}

{% if user|has_group:"premium" %}
    <a href="{% url 'premium_content' %}">プレミアムコンテンツ</a>
{% endif %}

テンプレートタグでより複雑な判定

# myapp/templatetags/auth_extras.py
from django import template

register = template.Library()

@register.simple_tag(takes_context=True)
def can_edit(context, obj):
    """記事の作者 or staff なら True"""
    request = context['request']
    user = request.user
    if not user.is_authenticated:
        return False
    if user.is_staff:
        return True
    return obj.author_id == user.id
{% load auth_extras %}

{% can_edit article as user_can_edit %}
{% if user_can_edit %}
    <a href="{% url 'article:edit' article.id %}">編集</a>
{% endif %}

ログイン強制は view 側で

テンプレートで条件分岐するだけではセキュリティ的に不十分です。データを返さないようにするには view 側で:

from django.contrib.auth.decorators import login_required, permission_required, user_passes_test

@login_required
def mypage(request):
    return render(request, 'mypage.html')

# ログインしてかつパーミッションを持っているか
@permission_required('polls.add_poll', raise_exception=True)
def add_poll(request):
    ...

# カスタム条件
@user_passes_test(lambda u: u.is_authenticated and u.email_verified)
def verified_only(request):
    ...

# クラスベースビューなら LoginRequiredMixin
from django.contrib.auth.mixins import LoginRequiredMixin

class MyPageView(LoginRequiredMixin, TemplateView):
    template_name = 'mypage.html'
    login_url = '/login/'

テンプレート内で次の URL を保持

ログイン後に元のページに戻すには:

<a href="{% url 'login' %}?next={{ request.path }}">ログイン</a>

{# ログインフォーム側 #}
<form method="post" action="{% url 'login' %}">
    {% csrf_token %}
    <input type="hidden" name="next" value="{{ next }}">
    {{ form.as_p }}
    <button type="submit">ログイン</button>
</form>

非匿名ユーザーの判定(旧 API)

記述意味備考
user.is_authenticatedログイン済か1.10+ から property(() 不要)
user.is_anonymous未ログインか同上
user.is_activeアカウント有効か停止アカウントは False
user.is_staff管理画面アクセス可admin/ で必要
user.is_superuser全権限perms 判定をバイパス

FAQ

Q: テンプレートで user が常に AnonymousUser になる
A: context processor の django.contrib.auth.context_processors.auth が抜けている可能性。settings.py を確認。または render() の代わりに自前の RequestContext を使い回している。

Q: DRF のテンプレートビューでログイン判定したい
A: APIView では request.user.is_authenticated を view 内で判定し、permission_classes = [IsAuthenticated] を設定。

Q: テンプレートで OR / AND を書きたい
A: {% if user.is_staff or user.is_superuser %} のように普通に or / and / not が使えます。