safe - import django template
Establecer todas las páginas para exigir el inicio de sesión, globalmente? (4)
Eche un vistazo al middleware . Estas son funciones que se ejecutan en varios puntos del ciclo de solicitud, por ejemplo, antes de que se llame a cada vista.
dado que es posible que desee excluir ciertas vistas de esto, veré, por ejemplo, cómo funciona el middleware csrf, junto con el decorador csrf_exempt.
ver [SOURCE]/django/views/decorators/csrf.py
y [SOURCE]/django/middleware/csrf.py
Deseo redirigir el acceso de los usuarios no autenticados a la página de inicio de sesión, después de lo cual el usuario conectado debe ser redirigido a la página solicitada originalmente.
De acuerdo con la documentación, esto se logra fácilmente usando el decorador @user_passes_test
. Pero parece que tendré que decorar cada vista, lo cual es una locura, hay demasiadas y es propensa a errores.
¿Cuál es una buena manera de activar esta funcionalidad globalmente (excepto por un pequeño conjunto fijo de vistas, como el login
)? Es decir, todo predeterminado para iniciar sesión solo + manejar la visualización anónima de forma explícita, cuando sea necesario.
Este blog proporciona exactamente lo que desea, utilizando Middleware: http://onecreativeblog.com/post/59051248/django-login-required-middleware
La forma en que resolví esto, fue tener mixin class, con el decorador (o el código que necesites). Aunque debes recordar llamar a la función super(Class, self).get(...)
, entonces supongo que no es tan diferente después de todo.
Por otro lado, tener un conjunto de mixins que hace cosas diferentes que encontré fue bastante bueno para obtener una visión muy simple de hacer muchas cosas sin mucho código.
Editar
Así es como lo hice en mi último proyecto:
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
Lo anterior es luego utilizado por las clases-vista (utilicé Django 1.3 con vistas basadas en clases):
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"
Necesita una vista para manejar el inicio de sesión (con la URL en la settings.LOGIN_URL
), que contiene un formulario con un campo oculto llamado next
. Este campo debe establecerse mediante una variable de contexto en la página a la que ir después de iniciar sesión correctamente.
Si todas las vistas heredan de la base mixin ( MyDefaultMixin
en mi código anterior), automáticamente comprobará que el usuario haya iniciado sesión iv la vista contiene un atributo llamado login_required
y está establecido en True
.
Puede haber mejores formas de hacerlo, pero esto es lo que hice y funcionó muy bien.
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)