Authentication & Registration:

This step, we need to solve authentication and registration error as much as possible.

login and logout:

First we need to create a new app

  • use the terminals to create a new app “accounts”

    1. [root@localhost Twittme]# python3 ./manage.py startapp accounts

    and we have an accounts directory here
    image.png

  • we need a bunch of views in /accounts/views.py ```python from django.shortcuts import render, redirect from django.contrib.auth import login, logout, authenticate from django.contrib.auth.forms import AuthenticationForm, UserCreationForm

def loginview(request, args, *kwargs): form = AuthenticationForm(request, data=request.POST or None) if form.is_valid(): user = form.getuser() # get user from the form if the request is valid login(request, user) # login with request and user return redirect(“/“) # back to the homepage

  1. context = {
  2. "form": form,
  3. "btn_label": "Login",
  4. "title": "Login",
  5. }
  6. return render(request, "accounts/auth.html", context)

def logout_view(request, args, *kwargs): if request.method == “POST”: logout(request) # logout with request return redirect(“/login”)

  1. context = {
  2. "form": None,
  3. "btn_label": "Logout?",
  4. "title": "Logout",
  5. }
  6. return render(request, "accounts/auth.html", context)

def register_view(request, args, *kwargs): form = UserCreationForm(request.POST or None) if form.is_valid(): print(form.cleaned_data)

  1. context = {
  2. "form": form,
  3. "btn_label": "Register",
  4. "title": "Register",
  5. }
  6. return render(request, "accounts/auth.html", context)
  1. and we need templates for those urls we render.
  2. - create directory /templates/accounts
  3. - create file /templates/accounts/auth.html
  4. ```html
  5. {% extends "base.html" %}
  6. {% block content %}
  7. <div class='col-10 col-md-4 mx-auto'>
  8. <h1>{{ title }}</h1>
  9. {% include "components/form.html" with form=form btn_label=btn_label %}
  10. </div>
  11. {% endblock content %}
  • modify /templates/components/form.html

    1. <form method='POST'> {% csrf_token %}
    2. {{ form.as_p }}
    3. <!--
    4. <button type='submit' class='btn btn-secondary'>Save</button>
    5. -->
    6. <button type='submit' class='btn btn-secondary'>{% if btn_label %}
    7. {{ btn_label }} {% else %}Save{% endif %}</button>
    8. </form>
  • register new app “accounts” in /Twittme/settings.py ```python

INSTALLED_APPS = [ ‘django.contrib.admin’, ‘django.contrib.auth’, ‘django.contrib.contenttypes’, ‘django.contrib.sessions’, ‘django.contrib.messages’, ‘django.contrib.staticfiles’,

  1. # third-party
  2. 'rest_framework',
  3. 'corsheaders',
  4. # internal
  5. 'accounts',
  6. 'tweets',

]

  1. - import and add new paths in /Twittme/urls.py
  2. ```python
  3. # ...
  4. from accounts.views import ( # new
  5. login_view,
  6. logout_view,
  7. register_view,
  8. )
  9. # ...
  10. urlpatterns = [
  11. path('admin/', admin.site.urls),
  12. path('api/tweets/', include('tweets.api.urls')),
  13. path('', tweets_list_view),
  14. path('login/', login_view), # new
  15. path('logout/', logout_view), # new
  16. path('register/', register_view), # new
  17. path('<int:tweet_id>', tweets_detail_view),
  18. path('profile/<str:username>', tweets_profile_view),
  19. ]
  20. # ...

to test, runserver
logout from admin page
image.png
use http://localhost/login/ to login in Twittme
image.png
successfully logged in, can tweet without error
image.png
use http://localhost/logout/ to logout
image.png
It is redirected to the login page
image.png
and the admin page shows it’s actually logged out
image.png

add description:

we need some more description in the logout page.

  • change context in /accounts/views.py

    1. def logout_view(request, *args, **kwargs):
    2. if request.method == "POST":
    3. logout(request) # logout with request
    4. return redirect("/login")
    5. # context = {
    6. # "form": None,
    7. # "btn_label": "Logout?",
    8. # "title": "Logout",
    9. # }
    10. context = {
    11. "form": None,
    12. "description": "Are you sure you want to logout?",
    13. "btn_label": "Click to Confirm",
    14. "title": "Logout",
    15. }
    16. return render(request, "accounts/auth.html", context)
  • add description part for /templates/accounts/auth.html ```html {% extends “base.html” %}

{% block content %}

{{ title }}

{% if description %}

{{ description }}

{% endif %} {% include “components/form.html” with form=form btn_label=btn_label %}

{% endblock content %}

  1. and refresh to see [http://localhost/logout/](http://localhost/logout/)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/1243266/1595743306309-07b6e5c8-13eb-4939-92dd-3f888fba8b1b.png#align=left&display=inline&height=312&margin=%5Bobject%20Object%5D&name=image.png&originHeight=623&originWidth=1064&size=29035&status=done&style=none&width=532)<br />we have a description about logout.
  2. <a name="yoZ2s"></a>
  3. #### register:
  4. access [http://localhost/register/](http://localhost/register/) to test register a new user<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/1243266/1595743436621-a625d88e-4485-4622-9cc3-8663b88ac3c7.png#align=left&display=inline&height=414&margin=%5Bobject%20Object%5D&name=image.png&originHeight=827&originWidth=1551&size=65329&status=done&style=none&width=775.5)<br />we can see what was passed in the terminal<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/1243266/1595743484734-2c344294-2679-4792-826f-a0b7df7a3803.png#align=left&display=inline&height=67&margin=%5Bobject%20Object%5D&name=image.png&originHeight=133&originWidth=949&size=19582&status=done&style=none&width=474.5)<br />but there was no new user created<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/1243266/1595743516523-72662069-af90-4ce7-9299-2dae1c1ae2f2.png#align=left&display=inline&height=367&margin=%5Bobject%20Object%5D&name=image.png&originHeight=735&originWidth=1377&size=59034&status=done&style=none&width=688.5)<br />so we need to register a new user from our passed set.
  5. before that, becuase we have built in methods, so that we already can check is the username unique or are password and password confirmation both the same one.
  6. - change register function in /accounts/views.py
  7. ```python
  8. def register_view(request, *args, **kwargs):
  9. form = UserCreationForm(request.POST or None)
  10. if form.is_valid():
  11. # print(form.cleaned_data)
  12. user = form.save(commit=True) # new
  13. user.set_password(form.cleaned_data.get("password1")) # new
  14. # password1 is password, password2 is password confirmation
  15. login(request, user) # new, login with request and user
  16. return redirect("/") # new, after register, redirect to homepage
  17. context = {
  18. "form": form,
  19. "btn_label": "Register",
  20. "title": "Register",
  21. }
  22. return render(request, "accounts/auth.html", context)

register a new account with http://localhost/register/
image.png
create successful
image.png