Python3.5.1 + Django2.0.3 で、簡単なCRUDアプリを作る（１）

#まずは一覧表示をしよう

##参考にしたサイト
https://eiry.bitbucket.io/tutorials/tutorial/crud_application.html
このサイトの情報は、バージョンが古いので、
これを参考にしつつ「Python3.5.1 + Django2.0.3」用に作成しました。

##前提
・「Python3.5.1 + Django2.0.3」の環境構築済み。
・AWSのCloud9を利用（あくまでも私の環境がこれであるだけです）

##まずは下準備
新しいプロジェクトを作ります。コマンドプロンプトから下のように打ち込みましょう。

```コマンド
ec2-user:~/environment $ django-admin startproject mytest
```

そしてアプリを作ります。

```コマンド
ec2-user:~/environment $ cd mytest
ec2-user:~/environment/mytest $ python3 manage.py startapp crud
```

アプリの概要は参考に示したサイトでご確認ください。
https://eiry.bitbucket.io/tutorials/tutorial/crud_application.html#id8

続いて以下の3つのファイルで下準備です。
###まずはおなじみsettings.pyの編集（アプリの追加）

```mytest/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'crud',  #追加
]
```

###そしてviews

```crud/views.py
from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return render(request, 'crud/index.html', {})

def add(request):
    return render(request, 'crud/edit.html', {})

def edit(request, editing_id):
    return render(request, 'crud/edit.html', {})

def delete(request):
    return HttpResponse('Delete')
```

###さらにurls.pyです。

```crud/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index),
    path('add', views.add),
    path('delete', views.delete),
    path('edit/<int:pk>/', views.edit),
]
```

このpathの書き方はDjango2より変わっています。
従来はurl(...という書き方でしたので、変更点をしっかりと確認してください。
特にeditの書き方はちょっとややこしいですね。
pkは、primary key の略です。ここでは、department.idを意味します。
その他、詳細はこちらを参考にされてみてください。
https://docs.djangoproject.com/en/2.0/releases/2.0/


###プロジェクト(mytest）の直下にあるurls.pyも編集します。

```mytest/urls.py
from django.urls import path, include
from django.contrib import admin

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('crud.urls')),
]
```

「path('admin/', admin.site.urls),」これはアプリの管理画面（admin）のURLがアプリのURLに「/admin/」をつけたものであることを示しています。
「path('crud/', include('crud.urls', namespace='crud')),」こちらは、crudフォルダにあるurls.pyを含めますよ(includeする）という意味です。

##テンプレートファイルを作る
続いてテンプレートファイル（実際に表示されるHTML）を作っていきましょう。


```mytest/crud/templates/crud/base.html
<!DOCTYPE html>
<html>
<head lang="ja">
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
```

```mytest/crud/templates/crud/index.html
{% extends 'crud/base.html' %}
{% block body %}
    index
{% endblock %}
```

```mytest/crud/templates/crud/edit.html
{% extends 'crud/base.html' %}
{% block body %}
    edit
{% endblock %}
```

##表示の動作確認
これで一通り出来たので、サーバーを起動して表示を確認してみましょう。
トップページ　[127.0.0.1/]
新規追加ページ　[127.0.0.1/add]
編集ページ　[127.0.0.1/edit/1]
削除ページ [127.0.0.1/delete]

IPアドレスはご自身の環境に合わせてください。
それぞれページが表示されたはずです。

もしエラーになったら、エラーメッセージをコピーして、そのままGoogleさんに聞いてみてくださいね。

##いよいよモデル開発
さてここまで出来たら基本的な枠組みはOKです。これからいよいよモデルを作っていきましょう。
繰り返しますが、参考にしているのは下記のサイトです。
https://eiry.bitbucket.io/tutorials/tutorial/crud_read.html
この内容を「Python3.5.1 + Django2.0.3」で改めています。
ここでは、会社内の組織をモデルとして定義します。

```model.py
from django.db import models
from django.utils import timezone

class Department(models.Model):
    name = models.CharField(max_length=255)
    name_short = models.CharField(max_length=127)
    created_date = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return self.name_short
```

ここでは
from django.utils import timezone
をくわえることで、
created_date = models.DateTimeField(default=timezone.now)
を機能させています。つまり、created_dateにはtimezoneの現在時刻を取ってくる設定にしているのですが、これを実現するために、あらかじめ「from django.utils import timezone」を記述しています。
あとはコマンドからマイグレーションを実行します。下記のようになればOKです。

```コマンド
ec2-user:~/environment/mytest $ python3 manage.py makemigrations
Migrations for 'crud':
  crud/migrations/0001_initial.py
    - Create model Department
ec2-user:~/environment/mytest $ python3 manage.py migrate                                                       
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, crud, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying crud.0001_initial... OK
  Applying sessions.0001_initial... OK
```

なんか、身に覚えのない記述（username_opts..とか）もたくさん出てきました。。。
これは最初のmigrationのためです。異常ではありませんのでこのまま進みます。

##shell画面からデータを作る
これから一覧画面を作りたいのですが、データが空っぽですので検証が出来ません。
なのでテストデータを作成しましょう。

```コマンド
ec2-user:~/environment/mytest $ python3 manage.py shell
```

まずは「総務部」「東京営業部」というデータを入れるために、下記のコマンドを入れてみます。

```
Department.objects.create(name='総務部',name_short='総務部')
Department.objects.create(name='東京営業部',name_short='東営')
```

データが入った確認しましょう。

```
Department.objects.all()
```

このコマンドの結果、総務部と東京営業部が出てくればOKです。


そして一覧表示の画面（index.html）のための設定です。
まずはviews.pyに、Departmentモデルを使用することを記載します。

```crud/views.py
from .models import Department
```

そして同じくviews.pyに、一覧表示のための記載をします。

```crud/views.py
def index(request):
    dept = {
        'departments': Department.objects.all(),
    }
    return render(request, 'crud/index.html', dept)
```

あとはHTMLですね。
ここは次のようにテーブルを使いました。

```templates/crud/index.html
{% extends 'crud/base.html' %}
{% block body %}
    <table border="1">
      <thead>
        <tr>
          <th>部門名</th>
          <th>略称</th>
          <th>登録日</th>
        </tr>
      </thead>
      <tbody>
        {% for department in departments %}
          <tr>
            <td>{{ department.name }}</td>
            <td>{{ department.name_short }}</td>
            <td>{{ department.created_at }}</td>
          </tr>
        {% endfor %}
      </tbody>
    </table>
{% endblock %}
```

これで、トップページにアクセスすると、先ほどshellから登録した2件のデータが表示されているかと思います。


次回に続く。