LoginSignup
17
14

More than 3 years have passed since last update.

【Django】template上で使用できる user について

Last updated at Posted at 2020-06-26

はじめに

 Djangoで、現在ログインしているユーザーの名前を画面上に表示させたい時はtemplate上で{{ user.username }}{{ user.get_username }}とすることで実現できる。しかし、このuserという変数はviews.pyでrender関数を用いてtempletesに渡したり、get_context_data()をオーバーライドして変数を追加したりしていないのになぜ使えるのか。ここに疑問を持ったので少し調べてみた。

結論

 templateで使用できる変数はcontext(={<変数名>: <変数>, .....})に格納されていて、このcontextは大きく以下の2種類の変数を含む。

  1. views.pyでrender関数などを用いて渡された変数
  2. settings.py内のTEMPLATESのOPTIONに指定されている'context_processers'で指定されるファイル内で定義された変数

 userは2.の説明にあたる変数であり、他にviews.pyで指定しなくても使える主な変数としてrequest, perm, messageなどがある。

どこに格納されているのか

 まずsetting.pyを見てみる。

config/setting.py
#
# 省略
#

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

#
# 省略
#

setting.pyにあるTEMPLATES.OPTIONS.context_processorsで指定されているファイルは、以下の4つ。
django.template.context_processors.debug
django.template.context_processors.request
django.contrib.auth.context_processors.auth・・・・・・・userの在処
django.contrib.messages.context_processors.messages

userの格納場所

django.contrib.auth.context_processors
#
# 省略
#

def auth(request):
    """
    Return context variables required by apps that use Django's authentication
    system.

    If there is no 'user' attribute in the request, use AnonymousUser (from
    django.contrib.auth).
    """
    if hasattr(request, 'user'):
        user = request.user
    else:
        from django.contrib.auth.models import AnonymousUser
        user = AnonymousUser()

    return {
        'user': user,
        'perms': PermWrapper(user),
    }

'user': userreturnすることによってuserがtemplate内で使えるようになる。user.usernameとしuser内のusername属性を取り出したり、AnonymousUserクラスをインスタンス化したあと、クラス内のget_userメソッドを使用しuser.get_usernameとすることでログイン中のユーザー名が表示可能となる。

(参考)

 一番下にget_username関数がある。

django.contrib.auth.models
class AnonymousUser:
    id = None
    pk = None
    username = ''
    is_staff = False
    is_active = False
    is_superuser = False
    _groups = EmptyManager(Group)
    _user_permissions = EmptyManager(Permission)

    def __str__(self):
        return 'AnonymousUser'

    def __eq__(self, other):
        return isinstance(other, self.__class__)

    def __hash__(self):
        return 1  # instances always return the same hash value

    def __int__(self):
        raise TypeError('Cannot cast AnonymousUser to int. Are you trying to use it in place of User?')

    def save(self):
        raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")

    def delete(self):
        raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")

    def set_password(self, raw_password):
        raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")

    def check_password(self, raw_password):
        raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")

    @property
    def groups(self):
        return self._groups

    @property
    def user_permissions(self):
        return self._user_permissions

    def get_user_permissions(self, obj=None):
        return _user_get_permissions(self, obj, 'user')

    def get_group_permissions(self, obj=None):
        return set()

    def get_all_permissions(self, obj=None):
        return _user_get_permissions(self, obj, 'all')

    def has_perm(self, perm, obj=None):
        return _user_has_perm(self, perm, obj=obj)

    def has_perms(self, perm_list, obj=None):
        return all(self.has_perm(perm, obj) for perm in perm_list)

    def has_module_perms(self, module):
        return _user_has_module_perms(self, module)

    @property
    def is_anonymous(self):
        return True

    @property
    def is_authenticated(self):
        return False

    def get_username(self):
        return self.username
17
14
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
17
14