6

I am trying to redirect a user who just logged in to his/her's respective account page.

This question has been asked a few times, but most of them are old and use static urls like /accounts/profile/: Django - after login, redirect user to his custom page --> mysite.com/username. I would like to use dynamic url naming to achieve this solution.

For example, what if my account landing page has the following url pattern?

url(r'^account/(?P<pk>\d+)/(?P<name>\w+)/$', AccountLanding.as_view(), name="account-landing" )`.

How would I pass the args in settings.py for LOGIN_REDIRECT_URL?

Community
  • 1
  • 1
Alex McLean
  • 2,524
  • 5
  • 30
  • 53
  • Your question is answered by Stu on the page you linked to. – Alasdair Mar 18 '16 at 19:39
  • 1
    @Alasdair No it's not. The reason I asked this again is to see if there have been any new developments in the 4 years since that was answered since Django has been updated a few times since then, which I think is perfectly reasonable to question. – Alex McLean Mar 18 '16 at 19:44
  • @Alasdair Stu never mentions that, as you said, it isn't possible to use dynamic arguments in the `LOGIN_REDIRECT_URL` which was basically what I was trying out; if that has changed or not. – Alex McLean Mar 18 '16 at 19:46
  • No, there hasn't been any change since that question was asked. [Ticket 19551](https://code.djangoproject.com/ticket/19551) was closed in favour of converting the login view to a class based view that would be easy to override ([ticket 17209](https://code.djangoproject.com/ticket/17209)). Since that hasn't happened yet, the only solution is to redirect via another page, as Stu and I describe. – Alasdair Mar 18 '16 at 20:03
  • The class-based `LoginView` was added in Django 1.11, so you can now override `get_success_url` and return the URL of the user's profile page. – Alasdair Dec 17 '18 at 17:09

2 Answers2

10

It isn't possible to use dynamic arguments (e.g. the primary key of the logged in user) in the LOGIN_REDIRECT_URL in your settings.py.

In Django 1.11+, you can subclass LoginView, and override get_success_url so that it dynamically redirects.

from django.contrib.auth.views import LoginView

class MyLoginView():

    def get_success_url(self):
        url = self.get_redirect_url()
        return url or reverse('account_landing', kwargs={'pk': self.request.user.pk, 'name': self.request.user.username})

Note the url = self.get_redirect_url() line is required to handle redirects back to the previous page using the querystring, e.g. ?next=/foo/bar

Then use your custom login view in your URL config.

url(r'^login/$', MyLoginView.as_view(), name='login'),

For earlier versions of Django, it isn't possible to customise the function-based login view in the same way.

One work around is to create a view that redirects to your landing page:

from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect

@login_required
def account_redirect(request):
    return redirect('account-landing', pk=request.user.pk, name=request.user.username)

Create a url pattern for this view:

urlpatterns = [
    url(r'^account/$', account_redirect, name='account-redirect'),
]

Then use that view as LOGIN_REDIRECT_URL:

LOGIN_REDIRECT_URL = 'account-redirect'
Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • LOGIN_REDIRECT_URL can also be assigned a view method, where it can be set to redirect to 'account-redirect/' where pk can be any particular key assigned to user. – anonDuck Mar 18 '16 at 19:39
  • @RA123 I don't understand what you mean. I've re-opened the question, in case you want to add your own answer. – Alasdair Mar 18 '16 at 19:41
  • 1
    No, sorry. I don't want to add an answer since this method is deprecated. But just wanted to mention it if OP may still want to use it. https://docs.djangoproject.com/en/1.9/ref/settings/#login-redirect-url – anonDuck Mar 18 '16 at 19:44
  • Oh, you mean they can use `LOGIN_REDIRECT_URL = 'path.to.account_redirect'` instead of `LOGIN_REDIRECT_URL = 'account-redirect'`? I don't think that has any advantages - you still have to create a view and url pattern, and as you say, using the dotted Python path like that is deprecated. – Alasdair Mar 18 '16 at 19:57
  • Yeah, that's why i just mentioned it here. It just came to my mind. – anonDuck Mar 18 '16 at 20:00
0

On Django 4.x there is a new attribute called next_page and you can use it as:

from django.contrib.auth.views import LoginView
from django.urls import reverse_lazy

class MyLoginView():
...
next_page = reverse_lazy('profile', kwargs={'id': pk},
                            name='username'))
...
Aymane Shuichi
  • 460
  • 5
  • 14