Ответ 1
Этот блог обеспечивает именно то, что вы хотите, используя Middleware: http://onecreativeblog.com/post/59051248/django-login-required-middleware
Я хочу перенаправить доступ пользователей, не прошедших проверку подлинности, на страницу входа в систему, после чего вошедший в систему пользователь должен быть перенаправлен на первоначально запрошенную страницу.
Согласно документации, это легко достигается с помощью декоратора @user_passes_test
. Но мне кажется, что мне нужно украсить все взгляды, которые сумасшедшие, их слишком много и они подвержены ошибкам.
Каков хороший способ включить эту функциональность глобально (за исключением небольшого фиксированного набора представлений, например login
)? То есть, по умолчанию все входить в систему в режиме "только" + обрабатывать анонимный просмотр явно, где это необходимо.
Этот блог обеспечивает именно то, что вы хотите, используя Middleware: http://onecreativeblog.com/post/59051248/django-login-required-middleware
посмотрите middleware. это функции, выполняемые в разных точках цикла запроса, например. перед вызовом каждого вида.
так как вы можете исключить некоторые виды из этого, я бы посмотрел, например. как работает промежуточное программное обеспечение csrf вместе с декоратором csrf_exempt.
см. [SOURCE]/django/views/decorators/csrf.py
и [SOURCE]/django/middleware/csrf.py
Как я решил, должен был быть класс mixin, с декоратором (или любым другим кодом, который вам нужен). Хотя вы должны помнить, что вы вызываете функцию super(Class, self).get(...)
, поэтому я думаю, что она не так уж и отличается.
С другой стороны, наличие набора mixins, который делает разные вещи, которые я нашел, было довольно хорошим для получения очень простого представления, чтобы сделать много без большого кода.
Так я сделал в своем последнем проекте:
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
Вышеуказанное затем используется классами view (я использовал 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"
Вам нужно посмотреть, как обрабатывать логин (с URL-адресом в settings.LOGIN_URL
), содержащий форму со скрытым полем под названием next
. Это поле должно быть задано с помощью контекстной переменной на страницу, которая будет использоваться после успешного входа в систему.
Если все виды наследуются от базового mixin (MyDefaultMixin
в моем коде выше), он автоматически проверяет, что пользователь зарегистрирован в iv, в представлении содержится атрибут с именем login_required
и установлен на True
.
Там могут быть лучшие способы сделать это, но это то, что я сделал, и это сработало очень хорошо.