mizzsugar’s blog

日々感じていることや学んだことを書きます。エンジニアリング以外にも書くかもしれません。

【Python・Django入門】ログイン画面、ユーザー登録画面を作る②

mizzsugar.hatenablog.com

こちらの記事の続きです。 ①の記事では、ユーザー登録機能とログイン機能を作りました。

この記事では、パスワードの変更機能とログアウト機能を作ります。

パスワード変更機能

urls.pyにパスワード変更画面のURLを追加します。

urls.py

from django.contrib import admin
from django.urls import path
import myApp.forms
import myApp.views

# 他にもありますが、今回はパスワード追加URLのみ
urlpatterns = [
    path("change_password", myApp.views.change_password)
]

forms.pyにパスワード変更用のフォームを定義します。

forms.py

from django import forms
from django.forms import PasswordInput

class ChangePasswordForm(forms.Form):
    new_password = forms.CharField(label='新しいパスワード', widget=PasswordInput())  # label = ''で画面に表示されるラベルを設定します。widget=PasswordInput()で、入力した値が●●●で表示されます。PasswordInput()を利用するには、PasswordInputをインポートする必要があります。

views.py

import myApp.forms

def change_password(request):
    if not request.user.is_authenticated: # このURLに移動した時点でログイン認証されていなかった場合
        return django.http.HttpResponseRedirect('/login') # ログイン画面に移動します
    if request.method == 'POST': # ログイン認証がされていて、POSTメソッドが実行された場合
        change_password_form = myApp.forms.ChangePasswordForm(request.POST) 
        new_password = request.POST['new_password']
        if len(new_password) < 8:
            change_password_form.add_error('new_password', "文字数が8文字未満です。")
        if not has_digit(new_password):
            change_password_form.add_error('new_password',"数字が含まれていません")
        if not has_alphabet(new_password):
            change_password_form.add_error('new_password',"アルファベットが含まれていません")
        if change_password_form.has_error('new_password'):
            return render(request, 'change_password.html', {'change_password_form': change_password_form}) # 新しいパスワードが8文字以上で英字数字含むことを満たしていない場合、パスワード変更画面に戻ります。
        user = request.user # userにリクエストを送ったユーザーの情報を代入します。ログインされているユーザーです。
        user.set_password(request.POST['new_password']) # set_password(password)でそのユーザーのパスワードを引数のパスワードに変更します。
        user.save() # save()でそのユーザーの情報の変更を保存します。
        # なお、set_password(password)でパスワードを変えると、自動的にログアウトされる動きをする
        return django.http.HttpResponseRedirect('/changed_password') # 変更したら、changed_passwordに移動します。
    else:
        change_password_form = myApp.forms.ChangePasswordForm()
    return render(request, 'change_password.html', {'change_password_form': change_password_form})

def changed_password(request):
    return render(request, 'changed_password.html') # このページに移動されている時にはログアウトされています。

templatesフォルダに、パスワード変更画面と、パスワードが変更された後に表示する画面のhtmlファイルを配置します。

changed_password.html(パスワードを変更する画面)

<form action="/change_password" enctype="multipart/form-data" method="POST">
    {% csrf_token %}
    {{ change_password_form }}
    <input type="submit" value="submit">
</form>

f:id:mizzsugar:20180704230907p:plain

changed_password.html(パスワードが変更された後の画面)

<p>パスワードの変更に成功しました。</p>

<a href="/login">ログイン画面で再度ログインする</a>
<-- ログアウトされた状態なので、ログイン画面へのリンクを追加します-->

f:id:mizzsugar:20180704231915p:plain

ログインしたら入れる、投稿画面と投稿一覧画面に、 ログアウト画面のリンクを追加します。

new_post.html

<a href="/change_password">パスワードを変更する</a>

<p>こんにちは、{{ user }}さん</p>
<form action="/post_new_post" enctype="multipart/form-data" method="POST">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="submit">
</form>

list.html

<p>こんにちは、{{ user }}さん</p>

<h2>POSTS</h2>


<a href="/change_password">パスワードを変更する</a>

{% load static %}
  <img src="{% static "coffee.jpg" %}">

{% for post in posts %}
    <img src = {% static post.file_path %}>
    <p>{{ post.comment }}</p>
    <p>{{ post.posted_at }}</p>
{% endfor %}

ログアウト機能

パスワード変更機能と比べて、ログアウト機能はすぐに終わります笑

urls.pyにパスワード変更画面のURLを追加します。

urls.py

from django.contrib import admin
from django.urls import path
import myApp.forms
import myApp.views

# 他にもありますが、今回はパスワード追加URLのみ
urlpatterns = [
    path("logout", myApp.views.logout)
]

templatesフォルダ内にログアウト画面のhtmlファイルを配置します。

logout.html

<p>ログアウトしました。</p>

<a href="/login">ログイン画面に移動する</a>

views.py

import django.http
from django.contrib.auth import authenticate, logout as django_logout # ここでは、def logout(request)内で利用するlogoutはdiango_logoutと定義します。同じ名前だとエラーになりました。


def logout(request):
    django_logout(request) # logoutモジュールのlogoutでログイン認証を解除します。
    return django.http.HttpResponseRedirect('/logout') # logout画面へ移動します。

ログインしたら入れる、投稿画面と投稿一覧画面に、 ログアウト画面のリンクを追加します。

new_post.html

<a href="/logout">ログアウト</a>
<a href="/change_password">パスワードを変更する</a>

<p>こんにちは、{{ user }}さん</p>
<form action="/post_new_post" enctype="multipart/form-data" method="POST">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="submit">
</form>

list.html

<p>こんにちは、{{ user }}さん</p>

<h2>POSTS</h2>


<a href="/logout">ログアウト</a>
<a href="/change_password">パスワードを変更する</a>

{% load static %}
  <img src="{% static "coffee.jpg" %}">

{% for post in posts %}
    <img src = {% static post.file_path %}>
    <p>{{ post.comment }}</p>
    <p>{{ post.posted_at }}</p>
{% endfor %}

後々、パスワードを忘れた時のための機能を追加します!