By default after login django redirects the user to an accounts/profile page or if you edit the LOGIN_REDIRECT_URL you can send the user to another page you specify in the settings.py.
This is great but I would like the user (after login) to be redirected to a custom page where the link to that page would look something like this: mysite.com/username
. So the default accounts/profile or the LOGIN_REDIRECT_URL settings would not work in this case since both are somehow static. In my case the username
section of the address changes for every user.
Any ideas how I can make it so when the user is logged in would go to a custom user page that has user's name in the address like: mysite.com/username
? Any input is truly appreciated.
This question is related to
django
django-views
django-urls
django-settings
Got into django recently and been looking into a solution to that and found a method that might be useful.
So for example, if using allouth the default redirect is accounts/profile. Make a view that solely redirects to a location of choice using the username field like so:
def profile(request):
name=request.user.username
return redirect('-----choose where-----' + name + '/')
Then create a view that captures it in one of your apps, for example:
def profile(request, name):
user = get_object_or_404(User, username=name)
return render(request, 'myproject/user.html', {'profile': user})
Where the urlpatterns capture would look like this:
url(r'^(?P<name>.+)/$', views.profile, name='user')
Works well for me.
If you're using Django's built-in LoginView
, it takes next
as context, which is "The URL to redirect to after successful login
. This may contain a query string, too." (see docs)
Also from the docs:
"If login is successful, the view redirects to the URL specified in next
. If next isn’t provided, it redirects to settings.LOGIN_REDIRECT_URL
(which defaults to /accounts/profile/)."
Example code:
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>
When using Class based views, another option is to use the dispatch method. https://docs.djangoproject.com/en/2.2/ref/class-based-views/base/
Example Code:
Settings.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'),
]
views.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)
Yes! In your settings.py define the following
LOGIN_REDIRECT_URL = '/your-path'
And have '/your-path' be a simple View that looks up self.request.user
and does whatever logic it needs to return a HttpResponseRedirect
object.
A better way might be to define a simple URL like '/simple'
that does the lookup logic there. The URL looks more beautiful, saves you some work, etc.
A simpler approach relies on redirection from the page LOGIN_REDIRECT_URL. The key thing to realize is that the user information is automatically included in the request.
Suppose:
LOGIN_REDIRECT_URL = '/profiles/home'
and you have configured a urlpattern:
(r'^profiles/home', home),
Then, all you need to write for the view home()
is:
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]))
where NAME_OF_PROFILE_VIEW
is the name of the callback that you are using. With django-profiles, NAME_OF_PROFILE_VIEW
can be 'profiles_profile_detail'.
Source: Stackoverflow.com