Есть ли способ заставить каждую страницу запрашивать логин без использования декораторов методов? [Дубликат]

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

def print_tuple(some_tuple=(1,2,3)):
    print some_tuple

print_tuple()        #1
print_tuple((1,2,3)) #2

Я дам вам подсказку. Вот разборка (см. http://docs.python.org/library/dis.html ):

# 1

0 LOAD_GLOBAL              0 (print_tuple)
3 CALL_FUNCTION            0
6 POP_TOP
7 LOAD_CONST               0 (None)
10 RETURN_VALUE

# 2

 0 LOAD_GLOBAL              0 (print_tuple)
 3 LOAD_CONST               4 ((1, 2, 3))
 6 CALL_FUNCTION            1
 9 POP_TOP
10 LOAD_CONST               0 (None)
13 RETURN_VALUE

Я сомневаюсь, что опытное поведение имеет практическое применение (кто действительно использовал статические переменные в C без размножающихся ошибок?)

] Как вы можете видеть, - преимущество производительности при использовании неизменяемых аргументов по умолчанию. Это может иметь значение, если это часто называемая функция или аргумент по умолчанию занимает много времени, чтобы построить. Кроме того, имейте в виду, что Python не C. В C у вас есть константы, которые в значительной степени свободны. В Python у вас нет этого преимущества.

20
задан Peladao 21 November 2011 в 21:35
поделиться

8 ответов

Выложил это в файл 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.

25
ответ дан meder omuraliev 21 August 2018 в 08:39
поделиться
  • 1
    Я думаю, что это решение действительно потрясающе. Я немного настроил его , чтобы поддержать redirect и получить URL-адрес для входа через reverse. – SummerBreeze 28 February 2013 в 14:37
  • 2
    Я думаю, что автор должен также ссылаться на onecreativeblog.com/post/59051248/… – Eiyrioü von Kauyf 9 February 2017 в 06:56
  • 3
    это не работает, если LOGIN_URL = '/', потому что после удаления косой черты в верхней части этого фрагмента кода полученная пустая строка соответствует любому URL-адресу! – user3182532 23 July 2017 в 09:52

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

http://www.djangobook.com/en/2.0/chapter17/ и http://docs.djangoproject.com/ ru / 1.2 / themes / http / middleware / # themes-http-middleware

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

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

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

2
ответ дан andyortlieb 21 August 2018 в 08:39
поделиться
  • 1
    Вы должны уточнить. – Byron Whitlock 9 July 2010 в 17:25
  • 2
    Я не знаком с использованием специального промежуточного программного обеспечения. Можете ли вы указать совместимый с django 1.2 фрагмент, который обрабатывает это? – meder omuraliev 9 July 2010 в 17:26
  • 3
    Я наткнулся на этот фрагмент: djangosnippets.org/snippets/1179 Хотя он был опубликован в 2008 году. Может ли кто-нибудь просмотреть и посмотреть, будет ли он использоваться? – meder omuraliev 9 July 2010 в 17:30
  • 4
    Да, этот сниппет должен работать нормально. – Sam Dolan 9 July 2010 в 18:00

Вот пример для промежуточного программного обеспечения нового стиля в 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-адреса входа.

-1
ответ дан Jack Cushman 21 August 2018 в 08:39
поделиться

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

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

11
ответ дан Justin Abrahms 21 August 2018 в 08:39
поделиться
  • 1
    Это решение кажется гораздо более элегантным, чем установка и поддержка вашего собственного промежуточного программного обеспечения. Прекрасно работает. – shacker 8 November 2014 в 22:19
  • 2
    Я создал middleware.py, который содержал from django.utils.deprecation import MiddlewareMixin, from stronghold.middleware import LoginRequiredMiddleware, class LoginRequiredStrongholdMiddleware(MiddlewareMixin, LoginRequiredMiddleware): pass. Затем я добавил этот пользовательский класс промежуточного ПО в файл настроек, а не в класс оплотов по умолчанию. Это работало в Django 1.10 – MiniGunnR 23 September 2016 в 05:56

Вот немного более короткое промежуточное ПО.

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.

8
ответ дан kaleissin 21 August 2018 в 08:39
поделиться

В дополнение к медиуму omuraliev ответьте, если вы хотите, чтобы этот текст был исключен (с регулярным выражением):

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 '..' в начале строки.

0
ответ дан magrif 21 August 2018 в 08:39
поделиться

Вот классический 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, а метод.
  • см. docs для получения дополнительной информации (хотя некоторые части не очень понятны).
2
ответ дан mehmet 21 August 2018 в 08:39
поделиться

Django Login Required Middleware

Поместите этот код в 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',
)

Like это: 'app_name.middleware.LoginRequiredMiddleware'

0
ответ дан Tree Nguyen 21 August 2018 в 08:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: