Webアプリ開発(Django+Vue.js+Docker)#12
こちらの記事の続きになります。
この記事では、ログイン画面を実装してみます。
バックエンド
Views.py
ログイン画面では、ユーザIDとパスワードを入力し、バックエンドでそれらを照らし合わせるという処理が必要になります。
まずは、ユーザIDとパスワードが送られてきたときに照らし合わせるという処理を書いていきましょう。
なので、メソッドはPOSTになりますね。
def login_view(request):
if request.method == 'GET':
param = {}
return render(request, 'login.html', param)
if request.method == 'POST':
password = request.POST.get('password')
username = request.POST.get('username')
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return HttpResponseRedirect(reverse('test:index'), {'user': user})
messages.error(request, '入力情報に間違いがあります')
return HttpResponseRedirect('.')
このような関数をViews.pyに追加します。
実はユーザ情報の照らし合わせはすでにauthenticateという関数があり、それを使用すれば簡単にログイン機能が実装できます。
また、このページを初期ページとし、ログアウト機能も実装しましょう。
ログアウト機能に関しても、Views.pyに以下の関数を追加するだけです。
def logout_account(request):
logout(request)
return HttpResponseRedirect(reverse('test:index'))
便利なことにlogout関数がすでにあります。
urls.py
それでは新たにファイルを追加したので、パスをつなげていきましょう。
testディレクトリ内のurls.pyに以下を追加します。
urlpatterns = [
path("", views.index, name="index"),
path('login/', views.login_view, name='login'),
path('logout', views.logout_account, name='logout'),
ついでに、、、
また、フロントエンドでのパスもつなぎます。
base.htmlのヘッダーのホームとログアウトの部分にパスを追加します。
<div class="collapse navbar-collapse show" id="navbarNavAltMarkup">
<div class="navbar-nav">
<a class="nav-link active" href="{% url 'test:index' %}">ホーム</a>
<a class="nav-link" href="{% url 'test:logout' %}">ログアウト</a>
</div>
</div>
また、ホームページ(index.html)では認証された自分物のホームページを表示するように、Views.pyのindex関数も変更しましょう。
Views.pyのindex関数を以下の様に変更しましょう。
def index(request):
if request.method == 'GET':
if request.user.is_authenticated:
param = {'date': timezone.now}
return render(request, 'index.html', param)
return HttpResponseRedirect(reverse('test:login'))
だいたいわかるかもしれませんが、indexページを表示する際は同時にauthenticatedされていることが必要になります。
そのため、logout関数でrequestのauthenticatedされていない状態になった場合はindexページの表示が拒否されるようになります。
つまり、login画面にリダイレクトすることになります。
フロントエンド
login.html
次はログイン画面の見た目を作ります。
templatesディレクトリ内に「login.html」ファイルを作成し以下をコピペします。
{% extends 'base.html' %}
{% block title %}ログイン{% endblock title %}
{% block content %}
<div>ようこそ!</div>
<form method="post" action="{% url 'test:login' %}">
{% csrf_token %}
<div class="mb-3">
<label class="form-label">ユーザ名</label>
<input class="form-control" name="username" type="text" />
</div>
<div class="mb-3">
<label class="form-label">パスワード</label>
<input name="password" type="password" class="form-control" />
</div>
<button type="submit" class="btn btn-primary">ログイン</button>
</form>
{% endblock content %}
これもいつも通りですね、ユーザIDとパスワードを入力するという事が違うだけで本質的には同じです。{% csrf_token %}も忘れずに。
実はもうこれでログイン機能ができています!
ログインページへ飛びます。
localhost/login
そして、以下で設定したスーパーユーザのユーザ名とパスワードを入力するとログインできます。
次は、新規登録部分も作成してみましょう。
新規登録
バックエンド
まずは、テストを保管する部分を作った時と同様に、ユーザ情報を保管する部分を作成しましょう。
models.pyで以下を追加します。
# Create your models here.
class UserInfo(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
free_text = models.CharField(max_length=500, blank=True)
このデータベースの変更を反映させるため一度、docker-compose downして、docker-compose buildをしてから、再度docker-compose upしましょう。
次に、View.pyにユーザ登録関数を作成します。
内容はフロントから、ユーザ情報が送られてくるので、それをテスト作成時と同じようにデータベースに登録するだけです。
以下関数を追加しましょう。
def create_user(request):
if request.method == 'GET':
return render(request, 'create_user.html')
if request.method == 'POST':
User.objects.create_user(username=request.POST.get('name'), password=request.POST.get('password'), email=request.POST.get('email'))
return HttpResponseRedirect(reverse('test:login'))
また、パスをつなぐことも忘れずに行いましょう。
urls.pyに以下を追加。
path("create_test/", views.create_test, name="create_test"),
フロントエンド
まず、templatesディレクトリ内に「create_user.html」ファイルを作成し以下をコピペします
{% extends 'base.html' %}
{% block title %}アカウント登録{% endblock title %}
{% block content %}
<div id="create_user">
<form method="post" action="{% url 'test:create_user' %}">
{% csrf_token %}
<div class="mb-3">
<label class="form-label">ユーザ名</label>
<input class="form-control" name="name" v-model="name" type="text" />
</div>
<div class="mb-3">
<label class="form-label">Email</label>
<input class="form-control" name="email" v-model="email" type="text" />
</div>
<div class="mb-3">
<label class="form-label">パスワード(半角英数字)</label>
<input name="password" type="password" class="form-control" />
</div>
<button type="submit" class="btn btn-primary"@click="CreateUser">登録</button>
</form>
</div>
<a href="{% url 'test:login' %}">ログイン画面へ</a>
{% endblock content %}
ログイン画面とほとんど同じですね。
次は、ログイン画面からこちらにアクセスできるようにします。
login.htmlで以下を最後に追加します。
<a href="{% url 'test:create_user' %}" style="font-size: 20px;">新規登録画面へ</a>
繋がりましたね!
試しに一つアカウントを登録してみてそれで入ってみてください。
新しいアカウントができていることが分かります。
ここで、今まで、バックエンドの処理でテストを取り出すときにユーザのフィルタリングをつけていた理由が分かったと思います。
フィルタリングしていないと、この新しいユーザに対しても別のユーザが登録したテストが見れるようになってしまうので、ユーザのフィルタリングは重要です。
また、ホーム画面のメッセージがずっとユーザさんになっているので、これも変えましょう。index.htmlでユーザさんとなっているところを以下に書き換えましょう。
<h5>{{user.username}}さん</h5>
今ログインしているユーザの名前に切り替わっていますね!