Django: después de iniciar sesión, redirija al usuario a su página personalizada –> mysite.com/username

8 minutos de lectura

avatar de usuario de avatar
avatar

De forma predeterminada, después de iniciar sesión, Django redirige al usuario a una página de cuentas/perfil o, si edita LOGIN_REDIRECT_URL, puede enviar al usuario a otra página que especifique en settings.py.

Esto es genial, pero me gustaría que el usuario (después de iniciar sesión) sea redirigido a una página personalizada donde el enlace a esa página se vería así: mysite.com/username. Por lo tanto, las cuentas/perfil predeterminados o la configuración de LOGIN_REDIRECT_URL no funcionarían en este caso, ya que ambos son de algún modo estáticos. en mi caso el username sección de los cambios de dirección para cada usuario.

¿Alguna idea de cómo puedo hacerlo para que cuando el usuario inicie sesión vaya a una página de usuario personalizada que tenga el nombre del usuario en la dirección como: mysite.com/username?

Avatar de usuario de Stu
Stu

Un enfoque más simple se basa en la redirección desde la página LOGIN_REDIRECT_URL. La clave a tener en cuenta es que la información del usuario se incluye automáticamente en la solicitud.

Suponer:

LOGIN_REDIRECT_URL = '/profiles/home'

y has configurado un urlpattern:

(r'^profiles/home', home),

Entonces, todo lo que necesitas escribir para la vista home() es:

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

@login_required
def home(request):
    return HttpResponseRedirect(
               reverse(NAME_OF_PROFILE_VIEW, 
                       args=[request.user.username]))

dónde NAME_OF_PROFILE_VIEW es el nombre de la devolución de llamada que está utilizando. Con perfiles Django, NAME_OF_PROFILE_VIEW puede ser ‘profiles_profile_detail’.

  • ¿Qué hay de las vistas basadas en clases?

    – Usuario

    19 de enero de 2015 a las 3:19

  • @Usuario el home view puede redirigir a cualquier patrón de URL, no importa si usa una vista basada en funciones o una vista basada en clases.

    – Alasdair

    18/03/2016 a las 19:45

  • El único problema con esto (que puede no ser un problema para usted) es que si hay un ?next=/someurl/ especificado en el get para el inicio de sesión, nunca llegará a LOGIN_REDIRECT_URL, por lo que la única forma de garantizar que terminar en la URL que desea es implementar su propia vista.

    – Lehrian

    4 oct 2018 a las 15:17

Avatar de usuario de Abid A
Cumplir con un

Puede autenticar e iniciar sesión como usuario como se indica aquí: https://docs.djangoproject.com/en/dev/topics/auth/default/#how-to-log-a-user-in

Esto le dará acceso al objeto Usuario desde el cual puede obtener el nombre de usuario y luego hacer un HttpResponseRedirect a la URL personalizada.

  • Olvidé mencionar que estoy usando django.contrib.auth.views que viene con django. ¿Puedo tener la URL personalizada descrita anteriormente en este caso?

    – avatar

    2 de febrero de 2011 a las 4:29

  • No estoy seguro si se puede personalizar auth.views.login hasta ese punto. Dicho esto, simplemente escribiría mi propia función de inicio de sesión, exactamente como la de la documentación a la que vinculé anteriormente.

    – Abid A

    2 de febrero de 2011 a las 4:38

¡Sí! En tu settings.py define lo siguiente

LOGIN_REDIRECT_URL = '/your-path'

Y haz que ‘/your-path’ sea una vista simple que busque self.request.user y hace cualquier lógica que necesita para devolver un HttpResponseRedirect objeto.

Una mejor manera podría ser definir una URL simple como '/simple' eso hace la lógica de búsqueda allí. La URL se ve más hermosa, te ahorra trabajo, etc.

Si está utilizando el incorporado de Django LoginViewse necesita next como contexto, que es “La URL a la que se redirigirá después de login. Esto también puede contener una cadena de consulta.” (ver documentos)

También de los documentos:

“Si el inicio de sesión es exitoso, la vista redirige a la URL especificada en next. Si no se proporciona next, se redirige a settings.LOGIN_REDIRECT_URL (que por defecto es /cuentas/perfil/).”

Código de ejemplo:

urls.py

from django.urls import path
from django.contrib.auth import views as auth_views

from account.forms import LoginForm # optional form to pass to view


urlpatterns = [
    ...

    # --------------- login url/view -------------------
    path('account/login/', auth_views.LoginView.as_view(
        template_name="login.html",  
        authentication_form=LoginForm, 
        extra_context={ 

            # option 1: provide full path
            'next': '/account/my_custom_url/', 

            # option 2: just provide the name of the url
            # 'next': 'custom_url_name',  
        },
    ), name="login"),

    ...
]

login.html

...

<form method="post" action="{% url 'login' %}">

  ...

  {# option 1 #}
  <input type="hidden" name="next" value="{{ next }}">

  {# option 2 #}
  {# <input type="hidden" name="next" value="{% url next %}"> #}

</form>

Al usar vistas basadas en clases, otra opción es usar el método de envío.
https://docs.djangoproject.com/en/2.2/ref/class-based-views/base/

Código de ejemplo:

Configuración.py

LOGIN_URL = 'login'
LOGIN_REDIRECT_URL = 'home'

urls.py

from django.urls import path
from django.contrib.auth import views as auth_views
urlpatterns = [
path('', HomeView.as_view(), name="home"),
path('login/', auth_views.LoginView.as_view(),name="login"),
path('logout/', auth_views.LogoutView.as_view(), name="logout"),
]

vistas.py

from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from django.views.generic import View
from django.shortcuts import redirect

@method_decorator([login_required], name="dispatch")
class HomeView(View):
    model = models.User

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return redirect('login')
        elif some-logic:
            return redirect('some-page') #needs defined as valid url
        return super(HomeView, self).dispatch(request, *args, **kwargs)

Avatar de usuario de Mohammad Hossein Bagheri
Mohammad Hossein Bagheri

De hecho, prefiero el método que @Stu y otros mencionaron, que consiste en crear una nueva URL y una vista para ella, de modo que podamos colocar allí la lógica de redirección. Es más fácil y los usuarios también pueden escribir example.com/profile en su navegador para ser redirigido a su perfil en example.com/profile/username/.

Pero otra forma que no requiere definir una URL adicional es extender el LoginView y redirigir usando el nombre de URL para la vista de perfil.

Digamos que tenemos dos aplicaciones llamadas accounts y pagesy hemos definido la página de perfil en el pages aplicación, algo como esto:

# pages/views.py
from django.views.generic import View
from django.http import HttpResponse

class ProfileView(View):
    def get(self, request, username):
        return HttpResponse('Hello ' + username + '!')

y la URLConf:

# pages/urls.py
from django.urls import path
from .views import ProfileView

app_name="pages"
urlpatterns = [
    path('profile/<str:username>/', ProfileView.as_view(), name="profile")
]

Tenga en cuenta que debemos definir app_name="pages" ya que lo necesitaremos para hacer referencia a las URL para el pages aplicación

Entonces, en el accounts aplicación, ampliamos la LoginView y agregue la lógica de redirección:

# accounts/views.py
from django.contrib.auth.views import LoginView
from django.urls import reverse

class CustomLoginView(LoginView):
    def form_valid(self, form):
        self.success_url_kwargs = {'username': form.cleaned_data['username']}
        return super().form_valid(form)

    def get_success_url(self):
        # 'pages:profile' refers to the 'profile' path in the 'pages' app.
        return reverse('pages:profile', kwargs=self.success_url_kwargs)
# accounts/urls.py
from django.urls import path, include
from .views import CustomLoginView

urlpatterns = [
    path('accounts/login/', CustomLoginView.as_view(), name="login"),
    path('accounts/', include('django.contrib.auth.urls'))
]

Después de un inicio de sesión exitoso, el form_valid() se llama al método y agregamos los parámetros que queremos usar en la URL del perfil al atributo de clase personalizado success_url_kwargs. Finalmente, llamando return super().form_valid(form) primero inicia la sesión del usuario y luego lo redirige a la URL proporcionada por el get_success_url() método (ver el código), que definimos para devolver la URL personalizada que queremos.

Tenga en cuenta que incluimos las URL para el auth app después de nuestra URL de inicio de sesión personalizada, para que la primera se resuelva cuando queramos acceder accounts/login/.

Además, si necesitáramos acceder a la instancia del modelo de usuario, podemos llamar form.get_user(). Esto puede ser útil en ciertos casos. Por ejemplo, si el usuario inicia sesión con correo electrónico y necesitamos su nombre de usuario, podemos hacer form.get_user().username.

Avatar de usuario de Jack L.
jack l

Me metí en django recientemente y estuve buscando una solución para eso y encontré un método que podría ser útil.

Entonces, por ejemplo, si usa allouth, la redirección predeterminada es cuentas/perfil. Cree una vista que únicamente redirija a una ubicación de su elección utilizando el campo de nombre de usuario de la siguiente manera:

def profile(request):
    name=request.user.username
    return redirect('-----choose where-----' + name + "https://stackoverflow.com/")

Luego cree una vista que lo capture en una de sus aplicaciones, por ejemplo:

def profile(request, name):
    user = get_object_or_404(User, username=name)
    return render(request, 'myproject/user.html', {'profile': user})

Donde la captura de urlpatterns se vería así:

url(r'^(?P<name>.+)/$', views.profile, name="user")

Funciona bien para mí.

¿Ha sido útil esta solución?