Login() Got an Unexpected Keyword Argument 'template_name' in Django Built-in Login Updated FREE
Login() Got an Unexpected Keyword Argument 'template_name' in Django Built-in Login
Django Logging Users In and Out
Last updated on July 27, 2020
Django provides congenital-in URL patterns and view functions which makes adding login and logout system to your site a cakewalk. But earlier we add them to our project, we volition create login and logout organization on our own by using some utility functions provided by the Django hallmark framework.
The cosign() and login() functions #
Django authentication framework (django.contrib.auth
) provides cosign()
and login()
functions whose job is to authenticate and login users respectively.
The authenticate()
part accepts ii keyword arguments, username
and password
and returns an object of type User
, if username
and countersign
are valid. Otherwise, it returns None
.
i two iii 4 v half dozen 7 8 9 10 11 12 13 14 15 | >>> >>> from django.contrib import auth >>> >>> user = auth . authenticate ( username = 'noisyboy' , countersign = 'pass' ) >>> user < User : noisyboy > >>> >>> if user is non None : ... impress ( "Credentials are valid" ) ... else : ... print ( "Invalid Credentials" ) ... Credentials are valid >>> >>> |
The cosign()
office merely verifies whether the credentials provided are valid or not. It doesn't login the user.
To login user nosotros apply login()
function. Information technology takes two arguments, request
object (HttpRequest
) and a User
object. To login user it saves the user's ID in the session, using Django session framework.
In one case a user is logged in, he should exist able to logout and this is the responsibility of logout()
part.
The logout() function #
To logout users we use logout()
function. It accepts a request (HttpRequest
) object and returns None
. Calling logout()
office completely deletes the session data associated with the logged in user.
It is important to note that calling logout()
office doesn't throw any errors if the user is not logged in.
The logout()
role also removes the cookie from the browser.
Another Login System #
Now nosotros have enough knowledge to roll out our own login system.
In the weblog's app views.py
add login()
, logout()
and admin_page()
views as follows:
TGDB/django_project/web log/views.py
1 two iii 4 v 6 seven 8 9 x eleven 12 13 fourteen 15 16 17 eighteen xix 20 21 22 23 24 25 26 27 28 29 thirty 31 32 33 34 35 36 37 38 | #... from django_project import helpers from django.contrib import auth #... def lousy_logout ( asking ): #... def login ( request ): if request . user . is_authenticated (): return redirect ( 'admin_page' ) if request . method == 'Mail' : username = request . POST . get ( 'username' ) password = request . POST . get ( 'password' ) user = auth . authenticate ( username = username , password = countersign ) if user is not None : # right username and password login the user auth . login ( request , user ) return redirect ( 'admin_page' ) else : messages . fault ( request , 'Fault incorrect username/countersign' ) render render ( asking , 'blog/login.html' ) def logout ( request ): auth . logout ( request ) return render ( asking , 'blog/logout.html' ) def admin_page ( request ): if non request . user . is_authenticated (): return redirect ( 'blog_login' ) render return ( request , 'weblog/admin_page.html' ) |
Then create three templates login.html
, logout.html
and admin_page.html
every bit follows:
TGDB/django_project/weblog/templates/blog/login.html
1 ii 3 4 5 vi vii 8 9 10 eleven 12 13 14 15 16 17 18 nineteen twenty 21 22 23 24 25 26 27 28 29 thirty 31 32 33 34 35 36 37 38 39 40 41 42 43 | {% extends "web log/base.html" %} {% block title %} Blog - {{ block .super }} {% endblock %} {% cake content %} <div course="content"> <div class="section-inner clearfix"> <h3>Login Form</h3> {% if messages %} <ul> {% for message in messages %} <li> {{ message }} </li> {% endfor %} </ul> {% endif %} <course action="" method="post"> {% csrf_token %} <table> <tr> <td><label for="id_username">Enter username</label></td> <td><input type="text" id="id_username" name="username"></td> </tr> <tr> <td><label for="id_username">Enter password</label></td> <td><input type="password" id="id_password" proper noun="password"></td> </tr> <tr> <td></td> <td><input type="submit" value="Submit"></td> </tr> </table> </class> </div> </div> {% endblock %} |
TGDB/django_project/blog/templates/blog/logout.html
1 two 3 4 v six vii eight 9 x 11 12 xiii 14 15 sixteen 17 | {% extends "weblog/base of operations.html" %} {% block title %} Blog - {{ block .super }} {% endblock %} {% cake content %} <div grade="content"> <div class="section-inner clearfix"> <p>Y'all are logged out. <a href=" {% url 'blog_login' %} ">Click hither</a> to login once again.</p> </div> </div> {% endblock %} |
TGDB/django_project/blog/templates/blog/admin_page.html
one ii three 4 5 6 7 viii 9 10 11 12 13 14 xv 16 17 xviii 19 20 21 22 23 24 25 26 27 28 29 | {% extends "blog/base.html" %} {% cake title %} Weblog - {{ block .super }} {% endblock %} {% block content %} <div class="content"> <div course="section-inner clearfix"> <p>Welcome {{ asking.user.username }} !</p> <p>User Details:</p> <ul> <li>Email: {{ request.user.username.email | default :"NA" }} </li> <li>SuperUser: {{ request.user.is_superuser }} </li> <li>Staff: {{ request.user.is_staff }} </li> <li>Date Joined: {{ request.user.date_joined }} </li> <li>Concluding Login: {{ request.user.last_login }} </li> </ul> <p><a href=" {% url 'blog_logout' %} ">Logout</a></p> </div> </div> {% endblock %} |
Finally, add the following URL patterns in the blog'southward urls.py
file:
TGDB/django_project/weblog/urls.py
#... urlpatterns = [ url ( r '^login/$' , views . login , name = 'blog_login' ), url ( r '^logout/$' , views . logout , name = 'blog_logout' ), url ( r '^admin_page/$' , views . admin_page , name = 'admin_page' ), url ( r '^lousy-login/$' , views . lousy_login , name = 'lousy_login' ), #... ] |
Start the development server and visit http://127.0.0.one:8000/login/
. You should get a page like this:
Enter correct username and password and you will exist greeted with a folio like this:
Zippo extraordinary here, we are just using some of the attributes we have learned in before lesson to get some information about the current logged in user.
To logout, click the logout link at the bottom of the folio.
Using built-in login() and logout() views #
Django provides two views django.contrib.auth.login()
and django.contrib.auth.logout()
to login and logout users respectively.
To use these views, import django.contrib.auth
package and then add the following two URL patterns in the cadmin's app urls.py file:
TGDB/django_project/cadmin/urls.py
#... from . import views from django.contrib.auth import views as auth_views urlpatterns = [ url ( r '^accounts/login/$' , auth_views . login , name = 'login' ), url ( r '^accounts/logout/$' , auth_views . logout , name = 'logout' ), url ( r '^mail/add/$' , views . post_add , name = 'post_add' ), #... ] |
Past default, Django uses /accounts/login/
and /accounts/logout/
URL for login and logout respectively.
Salvage the urls.py
file and visit http://127.0.0.1:8000/cadmin/accounts/login/
. You lot will go a TemplateDoesNotExist
exception equally follows:
The trouble is that by default, django.contrib.auth.login()
view looks for registration/login.html
template in the templates
directory of the auth app (django.contrib.auth
). Because there is no such file in the templates
directory of the auth app, Django raises a TemplateDoesNotExist
exception.
We can pass a unlike template to the django.contrib.auth.login()
view using the template_name
keyword statement as follows:
url ( r '^accounts/login/$' , auth_views . login , { 'template_name' : 'blog/login.html' }, name = 'login' ) |
Similarly, past default the django.contrib.auth.logout()
view uses registration/logged_out.html
template from the admin app (django.contrib.admin
). This is the same template which you would see if you logout from the Django Admin site.
Visit http://127.0.0.i:8000/cadmin/accounts/logout/
and see it yourself.
Only as with django.contrib.auth.login()
view, we tin can utilise a different template by passing template_name
keyword statement to django.contrib.auth.logout()
view equally follows:
url ( r '^accounts/logout/$' , auth_views . logout , { 'template_name' : 'blog/logout.html' }, name = 'logout' ) |
We will create custom templates for login and logout page. Then alter login and logout URLs to include template name in cadmin'southward urls.py
file as follows:
TGDB/django_project/cadmin/urls.py
#... urlpatterns = [ url ( r '^accounts/login/$' , auth_views . login , { 'template_name' : 'cadmin/login.html' }, proper noun = 'login' ), url ( r '^accounts/logout/$' , auth_views . logout , { 'template_name' : 'cadmin/logout.html' }, proper noun = 'logout' ), url ( r '^mail service/add/$' , views . post_add , name = 'post_add' ), #... ] |
Earlier we create login and logout templates, allow's create another URL design which points to the root URL (i.e http://127.0.0.1:8000/cadmin/
) of the cadmin app. Add a URL blueprint named habitation
to the urlpatterns
listing in urls.py
file every bit follows:
TGDB/django_project/cadmin/urls.py
#... urlpatterns = [ url ( r '^$' , views . dwelling house , proper name = 'home' ), url ( r '^accounts/login/$' , auth_views . login , { 'template_name' : 'cadmin/login.html' }, name = 'login' ), #... ] |
Then, in the cadmin views.py
file add the home()
view only below post_update()
view as follows:
TGDB/django_project/cadmin/views.py
#... def post_update ( request , pk ): #... def home ( request ): if non request . user . is_authenticated (): return redirect ( 'login' ) return return ( asking , 'cadmin/admin_page.html' ) |
The only affair that remains now is the templates for the login, logout and admin page. Let's start by creating login template first.
Create a new file named login.html
within cadmin app'due south templates
directory (i.e cadmin/templates/cadmin/
) and add the following code to information technology:
TGDB/django_project/cadmin/templates/cadmin/login.html
one 2 iii 4 5 6 7 eight 9 10 11 12 13 xiv xv 16 17 18 19 20 21 22 | {% extends "cadmin/base of operations.html" %} {% block content %} <div class="login"> <h1>The Not bad Django Weblog - Login</h1> <class method="post" activeness=""> {% csrf_token %} <tabular array> {{ class.as_table }} <tr> <td> </td> <td><input type="submit" value="Submit"></td> </tr> </table> </form> </div> {% endblock %} |
The value of the class
template variable will be provided past django.contrib.auth.login()
view using context.
Create another template named logout.html
with the following lawmaking.
TGDB/django_project/cadmin/templates/cadmin/logout.html
{% extends "cadmin/base.html" %} {% cake content %} <div course="logout"> <p>You have successfully logged out. <a href=" {% url 'login' %} ">Click</a> to login again.</p> </div> {% endblock %} |
Finally, create admin_page.html
and add the following lawmaking to it.
TGDB/django_project/cadmin/templates/cadmin/admin_page.html
1 2 three four 5 6 seven 8 9 10 eleven 12 xiii 14 xv 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | {% extends "weblog/base of operations.html" %} {% block championship %} Web log - {{ block .super }} {% endblock %} {% block content %} <div class="content"> <div class="section-inner clearfix"> <p>Welcome {{ request.user.username }} !</p> <p>User Details:</p> <ul> <li>Email: {{ request.user.email | default :"NA" }} </li> <li>SuperUser: {{ request.user.is_superuser }} </li> <li>Staff: {{ request.user.is_staff }} </li> <li>Date Joined: {{ asking.user.date_joined }} </li> <li>Concluding Login: {{ request.user.last_login }} </li> </ul> <p><a href=" {% url 'logout' %} ">Logout</a></p> </div> </div> {% endblock %} |
Our login view is almost ready. Visit http://127.0.0.1:8000/cadmin/accounts/login/
and endeavour logging in using wrong username and password. You will be greeted with errors similar this:
Try logging in one more fourth dimension using the right username and password. If user logged in successfully so the django.contrib.auth.login()
view will redirect the user to /accounts/profile/
URL, this is Django'south some other default setting kicking in.
We don't accept any URL pattern in cadmin'southward urls.py
for /accounts/profile/
that'southward why an HTTP 404 fault is displayed.
We tin override this setting by calculation a hidden field (in login.html
) named adjacent
with the URL to redirect subsequently login.
<td><input type="hidden" name="next" value="/cadmin/"></td>
This will redirect the user to http://127.0.0.1:8000/cadmin/
, afterward successful login.
Instead of hardcoding the URL. We could also pass the value of the next
field using query string like this:
http://127.0.0.i:8000/cadmin/accounts/login/?next=/cadmin/
Open login.html
and add together the subconscious field named adjacent
equally follows:
TGDB/django_project/cadmin/templates/cadmin/login.html
1 2 3 4 v 6 7 8 9 10 11 12 | {# ... #} <form method="mail service" action=""> {% csrf_token %} <table> {{ class.as_table }} <tr> <td><input type="hidden" proper noun="next" value=" {{ next | default :'/cadmin/' }} "></td> <td><input type="submit" value="Submit"></td> </tr> </tabular array> </grade> {# ... #} |
This is how the above code works:
If we don't provide any value to next
form field as query string then the default value i.eastward /cadmin/
volition exist used. Otherwise, the user will exist redirected to the URL given past the side by side
equally a query string.
Visit http://127.0.0.one:8000/cadmin/accounts/login/
, enter correct username/password and striking enter. This time y'all will be redirected to http://127.0.0.1:8000/cadmin/
, which looks like this:
To logout click "Logout" link at the lesser of the page or visit http://127.0.0.1:8000/cadmin/accounts/logout/
and you will run across a page similar this:
Our login and logout system is working as expected, but from the usability point of view, there is nevertheless one problem.
Visit http://127.0.0.1:8000/cadmin/accounts/login/
once again and login using the correct username and password. As expected, you will be redirected to http://127.0.0.1:8000/cadmin/
. At this betoken, if we visit http://127.0.0.1:8000/cadmin/accounts/login/
over again, Django volition redisplay the login the form. Redisplaying login course to a logged in user is absolutely pointless.
Nosotros tin can change this behavior by creating a custom login view function. Open cadmin app'due south views.py
and suspend the login()
view every bit follows:
TGDB/django_project/cadmin/views.py
one ii 3 four 5 6 7 8 ix 10 eleven 12 13 | #... from blog.models import Post , Author , Category , Tag from django.contrib.auth import views as auth_views #... def habitation ( request ): #... def login ( request , ** kwargs ): if request . user . is_authenticated (): return redirect ( '/cadmin/' ) else : return auth_views . login ( asking , ** kwargs ) |
Goose egg new here except the additional **kwargs
statement. The kwargs
enables us to pass the all the extra keyword arguments passed to this view function to the congenital-in django.contrib.auth.login()
view function.
Hither is how information technology works:
The login()
view first checks whether the user is authenticated or not. If the user is authenticated and so information technology volition redirect him to the admin page. Otherwise, it volition display the login form past calling built-in django.contrib.auth.login()
view.
Next, nosotros have to update our login URL pattern to apply our login()
view instead of i provided by Django Authentication framework. Update login
URL pattern in urls.py
as follows:
TGDB/django_project/cadmin/urls.py
#... urlpatterns = [ url ( r '^$' , views . home , name = 'home' ), url ( r '^accounts/login/$' , views . login , { 'template_name' : 'blog/login.html' }, proper noun = 'login' ), #... ] |
Now if you visit http://127.0.0.1:8000/cadmin/accounts/login/
afterward logging in, you will be redirected to http://127.0.0.1:8000/cadmin/
.
Limiting Access #
The whole point of implementing login system to our site is to forestall unauthorized access to administrative pages.
A unproblematic manner to restrict admission to a page is to first cheque whether the user is authenticated or not using is_authenticated()
method then redirect the user appropriately. For example:
def our_view ( request ): if non request . user . is_authenticated (): render redirect ( "login" ) return render ( request , 'app/view.html' ) |
Nosotros have already employed this technique in the home()
and login()
view functions.
TGDB/django_project/cadmin/views.py
1 two 3 four 5 half-dozen seven 8 9 ten 11 12 thirteen | #... def domicile ( request ): if not request . user . is_authenticated (): return redirect ( 'login' ) return render ( request , 'cadmin/admin_page.html' ) def login ( request , ** kwargs ): if request . user . is_authenticated (): render redirect ( '/cadmin/' ) else : return auth_views . login ( asking , ** kwargs ) |
In Django, the preferred way to limit access to pages is to apply login_required
decorator. To utilize login_required
decorator you must import it from django.contrib.auth.decorators
.
Let's update home()
view to use login_required
decorator as follows:
TGDB/django_project/cadmin/views.py
#... from django.contrib.auth import views every bit auth_views from django.contrib.auth.decorators import login_required #... @login_required def dwelling house ( request ): return render ( request , 'cadmin/admin_page.html' ) #... |
Here is how the login_required
decorator work:
If the user is not logged then it volition redirect the user to /accounts/login/
(Django'due south default login URL), passing the current absolute URL as a value to the side by side
query parameter. For instance, open your browser and visit http://127.0.0.1:8000/cadmin/
(without logging in). The login_required
will redirect you to http://127.0.0.1:8000/accounts/login/?next=/cadmin/
URL.
On the other hand, if the user is logged in then the login_required
would do cypher. In the side by side section, we are going to alter Django'south default login URL i.eastward /accounts/login/
.
Updating default Login URL #
In the earlier sections, we have encountered many places where Django uses /accounts/login/
as default URL for login. To change default login URL we use LOGIN_URL
setting in settings.py
file. LOGIN_URL
accepts URL or name of the URL pattern. Open settings.py
file and add the following variable at the terminate of the file.
Here we are assigning the value of the name
aspect of login URL pattern from cadmin's urls.py
. In other words, the above code changes the default login URL from /accounts/login/
to /cadmin/accounts/login/
. As a result, if you try to visit a view which has login_required
decorator applied to it, you will exist redirected to /cadmin/accounts/login/
URL instead of /accounts/login/
.
In our instance, nosotros desire users to let users to login and logout using /cadmin/login/
and /cadmin/logout/
URLs respectively. To exercise so, open cadmin's urls.py
file and brand the following changes:
TGDB/django_project/cadmin/urls.py
#... urlpatterns = [ url ( r '^$' , views . home , name = 'home' ), url ( r '^login/$' , views . login , { 'template_name' : 'cadmin/login.html' }, proper name = 'login' ), url ( r '^logout/$' , auth_views . logout , { 'template_name' : 'cadmin/logout.html' }, name = 'logout' ), #... ] |
As nosotros are using named URL blueprint in LOGIN_URL
setting nosotros don't need to update annihilation else. At present our updated login and logout URLs are /cadmin/login/
and /cadmin/logout/
respectively. To verify the changes visit http://127.0.0.1:8000/cadmin/
and y'all will be redirected to http://127.0.0.one:8000/cadmin/login/?side by side=/cadmin/
.
Enter right username and password and you will get a page like this:
Annotation: To checkout this version of the repository type git checkout 30a
.
Login() Got an Unexpected Keyword Argument 'template_name' in Django Built-in Login
DOWNLOAD HERE
Source: https://overiq.com/django-1-10/django-logging-users-in-and-out/
Posted by: charliebuthrotimily.blogspot.com
Comments
Post a Comment