Подтвердить что ты не робот

Django: Как я могу применить декоратор login_required на весь сайт (за исключением статического носителя)?

пример предоставляет фрагмент для представления уровня приложения, но что, если у меня есть много разных (и некоторых не-приложений) записей в мой файл "urls.py", включая шаблоны? Как я могу применить этот атрибут login_required к каждому из них?

(r'^foo/(?P<slug>[-\w]+)/$', 'bugs.views.bug_detail'),
(r'^$', 'django.views.generic.simple.direct_to_template', {'template':'homepage.html'}),
4b9b3361

Ответ 1

Отбросил это в файл 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)

Затем добавьте projectname.middleware.LoginRequiredMiddleware в мои MIDDLEWARE_CLASSES в settings.py.

Ответ 2

Для тех, кто пришел позже, вы можете обнаружить, что джанго-крепость хорошо подходит вам. Вы присваиваете белый список любым URL-адресам, которые вы хотите публиковать, остальные - это логин.

https://github.com/mgrouchy/django-stronghold

Ответ 3

Здесь немного более короткое промежуточное ПО.

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.

Ответ 4

Вот классическое LoginRequiredMiddleware для Django 1. 10+:

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 должен быть включен в MIDDLEWARE не MIDDLEWARE_CLASSES в settings.py.
  • is_authenticated - это bool, а не метод.
  • см. документы для получения дополнительной информации (хотя некоторые части не очень ясны).

Ответ 5

Используйте промежуточное программное обеспечение.

http://www.djangobook.com/en/2.0/chapter17/ а также http://docs.djangoproject.com/en/1.2/topics/http/middleware/#topics-http-middleware

Я предполагаю, что это не сильно изменилось в 1.2

Middleware позволяет вам создать класс с методами, которые будут обрабатывать каждый запрос в разное время/условия, как вы определяете.

например process_request (request) будет срабатывать перед вашим представлением, и вы можете принудительно выполнить аутентификацию и авторизацию на этом этапе.

Ответ 6

В дополнение к медиуму 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 '..' в начале нужной строки.

Ответ 7

Промежуточное ПО для входа в 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'

Ответ 8

Некоторые из предыдущих ответов либо устарели (более старая версия Django), либо вводят плохие методы программирования (жесткое кодирование URL-адресов, не использующих маршруты). Вот мое мнение о том, что оно более СУХОЕ и устойчивое/поддерживаемое (адаптировано из ответа Мехмета выше).

Чтобы подчеркнуть здесь улучшения, это полагается на предоставление 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'

Ответ 9

Вот пример для промежуточного ПО нового стиля в Django 1.10 +:

from django.contrib.auth.decorators import login_required
from django.urls import reverse

def login_required_middleware(get_response):
    """
        Require user to be logged in for all views. 
    """
    exceptions = {'/admin/login/'}
    def middleware(request):
        if request.path in exceptions:
            return get_response(request)
        return login_required(get_response, login_url=reverse('admin:login'))(request)
    return middleware

Этот пример освобождает форму входа администратора, чтобы избежать цикла перенаправления и использует эту форму в качестве URL-адреса входа.