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
?
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
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 LoginView
se 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)
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 pages
y 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
.
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í.