Progateで作ったWebアプリをDjangoで作ってみる2! Part2 -会員登録編-


目標物の確認

ProgateのNode.jsコースで作ったブログアプリと同じものをDjangoで作ってみます。

Djangoでのアプリ開発の一連の流れを整理するために記していきます。

完成イメージ

会員登録ページ

ブラウザから会員登録するためのviewを作っていきます。

from django.contrib.auth.models import UserでDjangoがあらかじめ準備しているUserテーブルをimportしています(☆1)。

methodがPOSTの場合、formに入力されたユーザー名、e-mailアドレス、パスワードがそれぞれusernameemailpasswordに格納されます(☆2)。

ユーザー名、e-mailアドレス、パスワードが一つでも空のままPOSTされてしまったとき、errorが表示されるようにします。まずはerrorsという空のリストを作成しておきます(☆3)。ユーザー名、e-mailアドレス、パスワードが空の場合、errorsに「それぞれが空です」というメッセージが格納されるようにします(☆4)。もし、一つでもerrorsにメッセージが入っていた場合、renderメソッドを使ってsignupページにerrorsが渡されるようにします(☆5)。{ 'errors' : errors }の左はkeyで、右がvalueです。つまり、このあと出てくるsignup.htmlファイルの{{errors}}key)でerrorsvalueが呼び出されます(☆6)。

errorsが空のまま、つまり、ユーザー名、e-mailアドレス、パスワードがちゃんと入力されていた場合、try exceptが実行されます。try except構文を見ていきます。

  1. try文が実行される
    user = User.objects.create_user(username, email, password)の中のcreate_userという部分が、新しくユーザーを作成するためのメソッドです。create_userメソッドが実行されることでUserテーブルに新しいデータが保存されます(☆7)。

  2. try文の実行結果、ユーザー名が重複しているとIntegrityErrorが送出される

  3. except IntegrityErrorという記載に従い、IntegrityErrorが送出されているのであれば、下の行のコードが実行される
    errors空リストにメッセージが格納され、renderメソッドを使ってsignupページにerrorsが渡されるようになります。

これでviewは完成しました。

blogapp/blog/views.py
from django.shortcuts import render
from django.views.generic import TemplateView
from django.contrib.auth.models import User # ☆1
from django.db import IntegrityError # ☆

class BlogTop(TemplateView):...

def signupview(request):
    if request.method == 'POST': # ☆2
        username = request.POST['username'] # ☆2
        email = request.POST['email'] # ☆2
        password = request.POST['password'] # ☆2
        errors = [] # ☆3

        if username == '': # ☆4
            errors.append('ユーザー名が空です')

        if email == '': # ☆4
            errors.append('メールアドレスが空です')

        if password == '': # ☆4
            errors.append('パスワードが空です')

        if len(errors) > 0: # ☆5
            return render(request, 'blog/signup.html', { 'errors' : errors }) # ☆6

        else:
            try:
                user = User.objects.create_user(username, email, password) # ☆7
                login(request, user)
                return redirect('blog:list')

            except IntegrityError: # ☆8
                errors.append('ユーザー登録に失敗しました')
                return render(request, 'blog/signup.html', {'errors' : errors })

    else:
        return render(request, 'blog/signup.html', {})

    return render(request, 'blog/signup.html', {})

続いて、HTMLファイルの編集を進めていきます。

エラー発生時にHTMLファイルにエラーメッセージを出すための実装をしていきます。

signupページの中にerrorsという追加のデータを入れます。もし、IntegrityErrorが発生した場合はrenderメソッドを使ってerrorsに格納されているerrorメッセージが入るようにしていきます(☆9)。

signup.html
{% load static %}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>BLOG</title>
    <link rel="stylesheet" href="{% static 'blog/style.css' %}">
  </head>
  <body>
    <div class="sign">
      <div class="container">
        <h1><a href="{% url 'blog:list' %}">BLOG</a></h1>
        <div class="panel">
          <h2>新規登録</h2>
          {% if errors %} <!--☆9-->
            <ul class="errors">
              {% for error in errors %} <!--☆9-->
                <li>{{ error }}</li> <!--☆9-->
              {% endfor %} <!--☆9-->
            </ul>
          {% endif %} <!--☆9-->
          <form action="" method="post">{% csrf_token %}
            <p>ユーザー名</p>
            <input type="text" name="username">
            <p>メールアドレス</p>
            <input type="text" name="email">
            <p>パスワード</p>
            <input type="password" name="password">
            <input type="submit" value="登録する">
            <a href="{% url 'blog:list' %}">一覧にもどる</a>
          </form>
        </div>
      </div>
    </div>
  </body>
</html>

最後に、urls.pyを編集して完了です。

blogapp/blog/urls.py
from django.urls import path
from .views import BlogTop, signupview

app_name = 'blog'

urlpatterns = [
    path('', BlogTop.as_view(), name='top'),
    path('signup/', signupview, name='signup'),

]

ページが完成しました。

空のまま登録ボタンを押すとエラーメッセージが表示されるようになりました!