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

# 目標物の確認

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

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

**完成イメージ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/147877a6-1b3a-25e2-7956-720596125802.png)

#会員登録ページ

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

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

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

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

```python: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）。

```html: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**を編集して完了です。

```python: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'),

]
```

ページが完成しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/6a4addda-0846-f8b6-26c6-9167d7722bd5.png)

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/881bcb78-9684-4f08-cf46-cb2d5f49c653.png)