認証されていないユーザーのアクセスをログインページにリダイレクトしたいのですが、その後、ログインしたユーザーは最初に要求されたページにリダイレクトされます。
ドキュメントによると、これは@user_passes_test
デコレータを使用して簡単に実現できます。しかし、私はすべてのビューを装飾する必要があるようです。これはクレイジーで、多すぎてエラーが発生しやすくなります。
この機能をグローバルにオンにする良い方法は何ですか(login
などの小さな固定ビューセットを除く)?つまり、すべてをデフォルトでログインのみに設定し、必要に応じて匿名表示を明示的に処理します。
from Django.shortcuts import redirect
from Django.conf import settings
class LoginRequiredMiddleware:
def __init__(self, get_response):
self.get_response = get_response
self.login_url = settings.LOGIN_URL
self.open_urls = [self.login_url] + \
getattr(settings, 'OPEN_URLS', [])
def __call__(self, request):
if not request.user.is_authenticated \
and not request.path_info in self.open_urls:
return redirect(self.login_url+'?next='+request.path)
return self.get_response(request)
私がこれを解決した方法は、デコレータ(または必要なコード)を使用してミックスインクラスを作成することでした。 super(Class, self).get(...)
関数を呼び出すことを覚えておく必要がありますが、結局のところそれほど違いはないと思います。
一方、私が見つけたさまざまなことを実行するミックスインのセットを持つことは、多くのコードなしで多くのことを実行するための非常に単純なビューを取得するのに非常に優れていました。
これは私が私の最後のプロジェクトでした方法です:
class BaseAuthMixin(object):
def auth_check(self, user):
return True
def dispatch(self, request, *args, **kwargs):
if not self.auth_check(request.user):
from Django.http import HttpResponseRedirect
from Django.contrib.auth import logout
is_web = False
is_live = False
if hasattr(self, 'get_url_name'):
from Django.core.urlresolvers import reverse
from Django.core.urlresolvers import NoReverseMatch
try:
next = reverse(self.get_url_name(), kwargs=kwargs)
except NoReverseMatch:
next = ''
else:
next= '?next=' + next
logout(request)
redirect_url = settings.LOGIN_URL
redirect_url += next
return HttpResponseRedirect(redirect_url)
else:
return super(BaseAuthMixin, self).dispatch(request, *args, **kwargs)
class LoginRequiredMixin(BaseAuthMixin):
"""
Check if the view needs the user to be logged in.
"""
def auth_check(self, user):
if not super(LoginRequiredMixin, self).auth_check(user):
return False
else:
if hasattr(self, 'login_required'):
if self.login_required and not user.is_authenticated():
return False
return True
class MyDefaultMixin(LoginRequiredMixin):
"""
Mixin that inherits from all common view mixins.
"""
pass
上記はビュークラスによって使用されます(クラスベースのビューでDjango 1.3を使用しました):
from Django.views.generic import TemplateView
class SomeViewClass(TemplateView, MyDefaultMixin):
# Used by 'LoginRequiredMixin' to check if a user has to be logged in
login_required = True
# Template for the Django TemplateView
template_name = "some_view_template.html"
ログインを処理するためのビュー(settings.LOGIN_URL
のURLを使用)が必要です。このビューには、next
という非表示フィールドを持つフォームが含まれています。このフィールドは、ログインに成功した後に移動するページにコンテキスト変数で設定する必要があります。
すべてのビューがベースミックスイン(上記のコードではMyDefaultMixin
)を継承している場合、ビューにlogin_required
という属性が含まれ、それがTrue
に設定されている場合、ユーザーがログインしていることを自動的に確認します。
これを行うにはもっと良い方法があるかもしれませんが、これは私がしたことであり、非常にうまく機能しました。
ミドルウェア をご覧ください。これらは、リクエストサイクルのさまざまなポイントで実行される関数です。各ビューが呼び出される前。
これから特定のビューを除外したい場合があるので、たとえばcsrfミドルウェアがどのように機能するかとcsrf_exemptデコレータ。
見る [SOURCE]/Django/views/decorators/csrf.py
および[SOURCE]/Django/middleware/csrf.py