We will continue to build our blog app where we left in the post writing-your-first-blog-app-in-django-part-17.
In this post we will see how we can redirect our users after they have logged into the application.In the previous post we had seen that if we run the server and if we go to http://127.0.0.1:8000/articles/create/ then it will send the user to the below page,if the user is not logged into the app already.
but,if we try to login here,it doesn’t take us to article create page,instead of that it will taking us to articles list page.
We will be shown this url: http://127.0.0.1:8000/accounts/login/?next=/articles/create/ ,if we are not logged into the system,but still trying to get the article create page.Now notice the url, it’s first gone to login url,but after that we have a query string and a query string is denoted by the question mark that starts the query string,than we have a query variable called next and that’s set equal to /articles/create.
So this is telling django that this is probably the url where user wants to go to next.It’s captured where we have come from,where we have tried to access and then when we login we probably want to go back to this /articles/create,but the trouble is how do we then access this variable right at the last form the query string and use it to relocate the user to that url.
Well when we render the login page,we are rendering the login.html template,we also send the request object and on the request object,we have access to these parameters that are at the end of the url written above,and we will access them via .get property.We will use the .get property on the request object to access this next variable.This request object is accessible inside login.html template or any other template.
So in the login.html template check whether the next parameter exists in the url or not.So change login.html template as following:
{% extends 'base_layout.html' %} {% block content %} <h1>Login</h1> <br> <br> <!--site-form is for stying purposes --> <form class="site-form" action="/accounts/login/" method="post"> {% csrf_token %} <!-- output all of fields which comes baked with django inbuilt form --> {{ form }} <!-- input field is hidden.So a user can't see it--> {% if request.GET.next %} <input type="hidden" name="next" value="{{ request.GET.next }}" /> {% endif %} <input type="submit" value="Login"> </form> <br><br> <p>Not got an account? <a href="{% url 'accounts:signup' %}">Sign Up</a></p> {% endblock %}
The request can be post request also.So also change the login_view function in accounts/views.py file as following:
from django.shortcuts import render,redirect from django.contrib.auth.forms import UserCreationForm,AuthenticationForm from django.contrib.auth import login,logout def signup_view(request): ''' If the request is post then we will take the data that we've got from the form and we want to somehow validate it and the way we do that is by following: ''' if request.method == 'POST': ''' What this instance is doing is essentially kind of valid in that data for us.If this data is okay(like user is already exists or not,password in long enough or not etc..).That's going to return us a instance of form that is either valid or invalid.If it is valid save that form to database. ''' form = UserCreationForm(request.POST) if form.is_valid(): #log the user in user = form.save() #after getting user we will try to login that user login(request, user) #redirect the user to articles list page return redirect('articles:list') #if the request is get then create a blank instance of user creation form. else: #create a new instance of the form form = UserCreationForm() #send that form to template return render(request, 'accounts/signup.html',{'form':form}) def login_view(request): ''' same as the signup view,in the login we can also have get request or post request if the request is post ''' if request.method == 'POST': form = AuthenticationForm(data=request.POST) if form.is_valid(): #log the user in #first of all we need to get what the user is,who's trying to log in user = form.get_user() #after getting user we will try to login that user login(request, user) #for redirecting if 'next' in request.POST: return redirect(request.POST.get('next')) else: return redirect('articles:list') #redirect the user to articles list page return redirect('articles:list') else: #this will be get request.When user clicks on login link or he will go to /accounts/login/ #we will send them a login form to the template and render that form in the browser #create a new instance of the form form = AuthenticationForm() return render(request, 'accounts/login.html',{'form':form}) def logout_view(request): if request.method == 'POST': #we don't need to pass the current user becuase he is already logged in as a user. #it will logout the current user logout(request) #once the user is logged out we'll do some kind of redirect. return redirect('articles:list')
So now you can check when we go to articles/create url,It will take us to login page,now login and you will be shown the article create page.
So in this post we have solved some url redirecting issues.