タイトル: テンプレート側のログイン判定
SEOタイトル: Django テンプレートでログイン判定する方法(is_authenticated / is_staff / グループ判定)
| この記事の要点 |
|
基本: is_authenticated
Django で「ログインしているか」を判定する最もシンプルな方法:
{# templates/base.html #}
user 変数はテンプレート内で自動的に使えます(後述の context processor が設定されている場合)。
context_processors の確認
テンプレートから user や request を参照できるのは、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 %}
{# 一般会員向け #}
マイページ
{% if user.is_staff %}
{# スタッフ向け(管理画面アクセス可) #}
管理画面
{% endif %}
{% if user.is_superuser %}
{# スーパーユーザー専用 #}
システム設定
{% endif %}
{% if user.email_verified %}
{# 自前で追加した属性も普通に使える #}
認証済
{% endif %}
{% else %}
ログイン
{% endif %}
パーミッション判定: {% if perms.app.action %}
Django の django.contrib.auth のパーミッションシステムに沿うなら:
{# polls アプリの change_poll 権限を持っているか #}
{% if perms.polls.change_poll %}
編集
{% endif %}
{# 複数 #}
{% if perms.polls.add_poll and perms.polls.delete_poll %}
{% 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" %}
編集者ダッシュボード
{% endif %}
{% if user|has_group:"premium" %}
プレミアムコンテンツ
{% 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 %}
編集
{% 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 を保持
ログイン後に元のページに戻すには:
ログイン
{# ログインフォーム側 #}
非匿名ユーザーの判定(旧 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 が使えます。