2012-06-08 10 views
17

Me encanta el @login_required decorator de django, pero hay una cosa que no puedo entender cómo hacerlo.Suprime el comportamiento "? Next = blah" en el decorador de login_required de django

Si un usuario no autenticado intenta visitar una página de @login_required (por ejemplo, "/ private-stuff /"), quiero devolverlos a la página de inicio (por ejemplo, "/ home /"). Pero no quiero agregar un argumento "? Next =" a la url. En otras palabras, solo quiero redireccionar a "/ home /", no "/ home /? Next =/private-stuff /".

¿Cómo puedo hacer eso? ¿Hay una mejor manera que simplemente escribir mi propio decorador?

Respuesta

6

Bueno, hay dos maneras en que puedo pensar. En primer lugar, sería la forma "correcta", en el sentido de que no está rompiendo ninguna funcionalidad, solo agrega nuevas funcionalidades: cree su propio decorador login_required. El problema es que Django tiene realmente metido el redireccionamiento después de la funcionalidad de inicio de sesión, y requiere muchas partes. El login_required decorator es realmente una envoltura alrededor del user_passes_test decorator, que a su vez llama al redirect_to_login view, y es la vista que agrega el parametro next a la cadena de consulta. En su decorador personalizado, puede transferir la totalidad o parte de esta funcionalidad directamente al decorador, pero deberá hacer referencia a los tres para obtener el código necesario.

El otro, y mucho más fácil opción, es la creación de algunos de middleware para eliminar la cadena de consulta si está configurado:

from django.conf import settings 
from django.http import HttpResponseRedirect 

class RemoveNextMiddleware(object): 
    def process_request(self, request): 
     if request.path == settings.LOGIN_URL and request.GET.has_key('next'): 
      return HttpResponseRedirect(settings.LOGIN_URL) 

Y, a continuación, añadir la ruta de importación a que middleware para MIDDLEWARE_CLASSES. Recuerde que en la fase de solicitud, el middleware se procesa de primero a último o de arriba hacia abajo, en otras palabras. Esto debería llegar relativamente temprano en la fase de solicitud, pero es posible que necesite jugar un poco con él para ver qué puede y qué no puede venir antes.

El único problema real con este método es que "rompe" la siguiente funcionalidad de redirección, y no de una manera muy intuitiva, si un desarrollador posterior hereda su base de código junto con un mandato para permitir la redirección, podría ser un poco desconcertante.

+2

has_key está en desuso. use 'in' en su lugar. –

+0

@PatrickBassut no está en desuso, está completamente eliminado en Python 3. He actualizado la respuesta para que sea compatible con python3. Python 2 está obsoleto, me pregunto por qué la gente todavía lo usa en 2017. –

34

¿No es simplemente como:

@decorators.login_required(redirect_field_name=None) 
+0

¿De verdad lo intentó? Esto fue hace unos meses, pero creo que probé redirect_url = None y no funcionó. – Abe

+2

Sí, lo probé con la versión actual de Django. Tenga en cuenta que el parámetro es 'redirect_field_name' y no' redirect_url'. – Danosaure

+0

¿Es eso parte de la funcionalidad estándar de @login_required? No puedo encontrar ninguna referencia a eso en los documentos de django https://docs.djangoproject.com/en/1.5/topics/auth/default/#the-login-required-decorator – bab

0
login(request, user) 
if request.POST['next']: 
    return redirect(request.POST['next']) 
else: 
    msg = u"Welcome..." 
    return render_to_response('members/welcome.html', {'msg':msg}, 
               context_instance=RequestContext(request)) 
+1

Lo mejor es agregar algo de contexto para explicar su respuesta, no solo el código simple. Eso hace que sea más útil no solo para este consultante, sino también para cualquier persona que pueda tener el mismo problema en el futuro. Consulte estas pautas sobre [cómo escribir una buena respuesta] (http://stackoverflow.com/help/how-to-answer) para obtener más información :) – starsplusplus

Cuestiones relacionadas