Django
cloud9
Python3
Django2.0

Python3.5.1 + Django2.0.3 で、簡単なCRUDアプリを作る(1)

まずは一覧表示をしよう

参考にしたサイト

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..とか)もたくさん出てきました。。。
とりあえずここではパスします。異常ではなさそうなので。

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件のデータが表示されているかと思います。

次回に続く。