I actually prefer the method @Stu and others mentioned, which is to create a new URL and a view for it, so that we can put the redirection logic there. It's easier and users can also type example.com/profile in their browser to get redirected to their profile at example.com/profile/username/.
But another way that doesn't require defining an additional URL, is to extend the LoginView and redirect using the URL name for the profile view.
Let's say we have two apps named accounts and pages, and we have defined the profile page in the pages app, something like this:
# 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 + '!')
and the 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')
]
Note that we must define app_name = 'pages' as we'll need it to refer to the URLs for the pages app.
Then, in the accounts app, we extend the LoginView and add the redirection logic:
# 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'))
]
After a successful login, the form_valid() method gets called, and we add the parameters we want to use in the profile URL to the custom class attribute success_url_kwargs. Finally, calling return super().form_valid(form) first logs the user in, and then redirects to the URL given by the get_success_url() method (see the code), which we define to return the custom URL we want.
Note that we included the URLs for the auth app after our custom login URL, so that the first one is resolved when we want to access accounts/login/.
Also, if we needed to access the user model instance, we can call form.get_user(). This can be useful in certain cases. For example, if the user logs in with email and we need his username, we can do form.get_user().username.