example は、アプリケーションレベルのビューのスニペットを提供しますが、テンプレートを含め、「urls.py」ファイルにさまざまな(およびアプリケーション以外の)エントリがたくさんある場合はどうなりますか?このlogin_requiredデコレータをそれぞれに適用するにはどうすればよいですか?
(r'^foo/(?P<slug>[-\w]+)/$', 'bugs.views.bug_detail'),
(r'^$', 'Django.views.generic.simple.direct_to_template', {'template':'homepage.html'}),
これをプロジェクトルートのmiddleware.py
ファイルにドロップしました( http://onecreativeblog.com/post/59051248/Django-login-required-middleware から取得)
from Django.http import HttpResponseRedirect
from Django.conf import settings
from re import compile
EXEMPT_URLS = [compile(settings.LOGIN_URL.lstrip('/'))]
if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
EXEMPT_URLS += [compile(expr) for expr in settings.LOGIN_EXEMPT_URLS]
class LoginRequiredMiddleware:
"""
Middleware that requires a user to be authenticated to view any page other
than LOGIN_URL. Exemptions to this requirement can optionally be specified
in settings via a list of regular expressions in LOGIN_EXEMPT_URLS (which
you can copy from your urls.py).
Requires authentication middleware and template context processors to be
loaded. You'll get an error if they aren't.
"""
def process_request(self, request):
assert hasattr(request, 'user'), "The Login Required middleware\
requires authentication middleware to be installed. Edit your\
MIDDLEWARE_CLASSES setting to insert\
'Django.contrib.auth.middlware.AuthenticationMiddleware'. If that doesn't\
work, ensure your TEMPLATE_CONTEXT_PROCESSORS setting includes\
'Django.core.context_processors.auth'."
if not request.user.is_authenticated():
path = request.path_info.lstrip('/')
if not any(m.match(path) for m in EXEMPT_URLS):
return HttpResponseRedirect(settings.LOGIN_URL)
次に、settings.pyのMIDDLEWARE_CLASSESにprojectname.middleware.LoginRequiredMiddleware
を追加しました。
後でこれに来た人にとっては、Django-strongholdがあなたのユースケースによく合っていることに気付くかもしれません。公開したいURLをホワイトリストに登録し、残りはログインが必要です。
これは少し短いミドルウェアです。
from Django.contrib.auth.decorators import login_required
class LoginRequiredMiddleware(object):
def process_view(self, request, view_func, view_args, view_kwargs):
if not getattr(view_func, 'login_required', True):
return None
return login_required(view_func)(request, *view_args, **view_kwargs)
以下を表示するためにログインする必要がない各ビューで、「login_required」をFalseに設定する必要があります。
関数ビュー:
def someview(request, *args, **kwargs):
# body of view
someview.login_required = False
クラスベースのビュー:
class SomeView(View):
login_required = False
# body of view
#or
class SomeView(View):
# body of view
someview = SomeView.as_view()
someview.login_required = False
これは、ログインビューについて何かをする必要があることを意味しますが、とにかく私はいつも自分のauth-backendを書くことになります。
以前の回答のいくつかは、時代遅れ(古いバージョンのDjango)であるか、不十分なプログラミング手法(URLをハードコーディングし、ルートを使用しない)を導入しています。これが私の見解ですDRYそして持続可能/維持可能( 上記のMehmetの答え から適応)。
ここでの改善点を強調するために、これはURLにルート名を付けることに依存しています(これは、変更されて末尾/先頭にスラッシュがあるハードコードされたURL/URIを使用するよりもはるかに信頼性があります)。
from Django.utils.deprecation import MiddlewareMixin
from Django.urls import resolve, reverse
from Django.http import HttpResponseRedirect
from my_project import settings
class LoginRequiredMiddleware(MiddlewareMixin):
"""
Middleware that requires a user to be authenticated to view any page other
than LOGIN_URL. Exemptions to this requirement can optionally be specified
in settings by setting a Tuple of routes to ignore
"""
def process_request(self, request):
assert hasattr(request, 'user'), """
The Login Required middleware needs to be after AuthenticationMiddleware.
Also make sure to include the template context_processor:
'Django.contrib.auth.context_processors.auth'."""
if not request.user.is_authenticated:
current_route_name = resolve(request.path_info).url_name
if not current_route_name in settings.AUTH_EXEMPT_ROUTES:
return HttpResponseRedirect(reverse(settings.AUTH_LOGIN_ROUTE))
そしてsettings.py
ファイルでは、以下を定義できます。
AUTH_EXEMPT_ROUTES = ('register', 'login', 'forgot-password')
AUTH_LOGIN_ROUTE = 'register'
これがDjango 1.10+の古典的なLoginRequiredMiddleware
:
from Django.utils.deprecation import MiddlewareMixin
class LoginRequiredMiddleware(MiddlewareMixin):
"""
Middleware that requires a user to be authenticated to view any page other
than LOGIN_URL. Exemptions to this requirement can optionally be specified
in settings via a list of regular expressions in LOGIN_EXEMPT_URLS (which
you can copy from your urls.py).
"""
def process_request(self, request):
assert hasattr(request, 'user'), """
The Login Required middleware needs to be after AuthenticationMiddleware.
Also make sure to include the template context_processor:
'Django.contrib.auth.context_processors.auth'."""
if not request.user.is_authenticated:
path = request.path_info.lstrip('/')
if not any(m.match(path) for m in EXEMPT_URLS):
return HttpResponseRedirect(settings.LOGIN_URL)
注目すべき違い:
path.to.LoginRequiredMiddleware
は、settings.pyのMIDDLEWARE_CLASSES
ではなくMIDDLEWARE
に含める必要があります。is_authenticated
はブール値でありメソッドではありません。ミドルウェアを使用します。
http://www.djangobook.com/en/2.0/chapter17/ および http://docs.djangoproject.com/en/1.2/topics/http/middleware/#topics -http-ミドルウェア
これは1.2ではあまり変わらなかったと思います
ミドルウェアを使用すると、定義したとおりに、さまざまな時間/条件ですべての要求を処理するメソッドを使用してクラスを作成できます。
たとえば、process_request(request)はビューの前に起動し、この時点で認証と承認を強制できます。
ビューがたくさんあり、どのビューにも触れたくない場合は、この問題にミドルウェアを使用できます。以下のコードを試してください。
import traceback
from Django.contrib.auth.decorators import login_required
class RejectAnonymousUsersMiddleware(object):
def process_view(self, request, view_func, view_args, view_kwargs):
current_route_name = resolve(request.path_info).url_name
if current_route_name in settings.AUTH_EXEMPT_ROUTES:
return
if request.user.is_authenticated:
return
return login_required(view_func)(request, *view_args, **view_kwargs)
注意:
Djangoログインが必要なミドルウェア
このコードをmiddleware.pyに入れてください:
from Django.http import HttpResponseRedirect
from Django.conf import settings
from Django.utils.deprecation import MiddlewareMixin
from re import compile
EXEMPT_URLS = [compile(settings.LOGIN_URL.lstrip('/'))]
if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
EXEMPT_URLS += [compile(expr) for expr in settings.LOGIN_EXEMPT_URLS]
class LoginRequiredMiddleware(MiddlewareMixin):
def process_request(self, request):
assert hasattr(request, 'user')
if not request.user.is_authenticated:
path = request.path_info.lstrip('/')
if not any(m.match(path) for m in EXEMPT_URLS):
return HttpResponseRedirect(settings.LOGIN_URL)
そして、settings.pyで:
LOGIN_URL = '/app_name/login'
LOGIN_EXEMPT_URLS=(
r'/app_name/login/',
)
MIDDLEWARE_CLASSES = (
# ...
'python.path.to.LoginRequiredMiddleware',
)
このように: 'app_name.middleware.LoginRequiredMiddleware'
meder omuralievに加えて、次のような免除URLが必要な場合は回答してください(正規表現を使用):
url(r'^my/url/(?P<pk>[0-9]+)/$', views.my_view, name='my_url')
次のようにEXEMPT_URLSリストに追加します。
LOGIN_EXEMPT_URLS = [r'^my/url/([0-9]+)/$']
r '..'必要な文字列の先頭。