Python
Django
GoogleAppEngine

[GoogleAppEngine]DjangoのClass-based View用の@login_required

More than 3 years have passed since last update.

はじめに

Google App Engine/Python で、ユーザーがログインしていなかったらログイン画面にリダイレクトしてくれる
@login_required というデコレータ。

https://cloud.google.com/appengine/docs/python/tools/webapp/utilmodule#login_required

appengine/ext/webapp/util.py
def login_required(handler_method):
  """A decorator to require that a user be logged in to access a handler.

  To use it, decorate your get() method like this:

    @login_required
    def get(self):
      user = users.get_current_user(self)
      self.response.out.write('Hello, ' + user.nickname())

  We will redirect to a login page if the user is not logged in. We always
  redirect to the request URI, and Google Accounts only redirects back as a GET
  request, so this should not be used for POSTs.
  """
  def check_login(self, *args):
    if self.request.method != 'GET':
      raise webapp.Error('The check_login decorator can only be used for GET '
                         'requests')
    user = users.get_current_user()
    if not user:
      self.redirect(users.create_login_url(self.request.uri))
      return
    else:
      handler_method(self, *args)
  return check_login

(コードは SDK より引用)

非常に便利なんですが、これは webapp にしか対応していないため
Django 用に書き直してみた。
Class-based View(クラスベース汎用ビュー)用です。

コード

util.py
# -*- coding: utf-8 -*-
from django.http import HttpResponsePermanentRedirect
from google.appengine.api import users


def login_required(handler_method):
    u"""Django の Class-based View 用デコレータ

    Example:
        class MyView(View):

            @login_required
            def get(self, request):
                user = users.get_current_user()
                ...
    """
    def check_login(self, request, *args):
        user = users.get_current_user()

        if not user:
            login_url = users.create_login_url(request.get_full_path())
            return HttpResponsePermanentRedirect(login_url)
        else:
            return handler_method(self, request, *args)

    return check_login