Django(Python)でシステム開発できるようになる記事_入門編

[株式会社デジサク](https://digisaku.co.jp) がお送りするプログラミング記事、
今回はPythonのWebアプリケーションフレームワーク「**Django**」について扱っていきます。


## はじめに

Pythonをはじめ、プログラミングが以前より身近になってきましたが
いざサービス開発にチャレンジすると色んな壁があります。


**『入門書やチュートリアルのコピペから卒業できない』**
**『コピペで作ってみたけど、それ以降のアレンジができない』**
**『自分が書いたコードが正しいのか何となく自信がない』**


これらを分析すると、下図のように**５つの要因**に分解できます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/a0c27549-1efa-0604-99fb-81107b949e3d.png)



本記事では**「実践フェーズ」**にフォーカスして**『実際に動くシステムを開発する』**ことを目標にします。
※**「基礎フェーズ」**についても別の記事で整理したのでリンクをご紹介しておきます。

（３）プログラミングの基礎：[Pythonでゼロからでもサービス開発・公開できる学習ロードマップ](https://qiita.com/Saku731/items/52a3bbacd002f26f408e)
（４）システムの設計を考える：[要件定義～システム設計ができる人材になれる記事](https://qiita.com/Saku731/items/741fcf0f40dd989ee4f8)



## 本記事の内容
全体を通して**『Django(Python)を使ったシステム開発の一連手順』**が身に付くよう書きました。
開発プロセスの全体理解から実際のプログラミングまで、網羅的に学べる内容にしてあります。

章立ては以下の通りです。


- **そもそもシステムってなに？**
- **DjangoのMVTモデルとは？**
- **Djangoのファイル構成**
- **Djangoの開発手順_初期設定**
- **Djangoの開発手順_機能追加**


一連手順が身に付いた後、自分で色々なパターンを試してみて
慣れた頃に**オリジナルのサービス開発**にチャレンジされてみて下さい。



※なお、SNSでもプログラミング情報を発信しています。
良いと感じて頂けたら[Twitter「Saku731」](https://twitter.com/digisaku710) もフォロー頂けると嬉しいです。


それでは始めていきましょう。

## そもそも「システム」ってなに？
まず最初に**「システム」という言葉の意味**を理解することが非常に大事です。
辞書では以下の様に紹介されています。

- **システム・・・多くの物事や、一連の働きを秩序立てた全体的なまとまり**

これをIT用語に変換すると、、

- **システム・・・多くの「データ」や、「一連の処理」を秩序立てた「プログラム」の集まり**


つまり、『個々のパーツを秩序立てて組み上げて完成するプラモデル』の様なイメージです。
その為には大きく分けて３種類のスキルが必要です。


**① 開発に必要なパーツを考えるスキル**
**② 個々のパーツを作るスキル**
**③ 秩序立てて組み上げるスキル**


以外に盲点となる**『① 開発に必要なパーツを考えるスキル』**については、
『[要件定義～システム設計ができる人材になれる記事](https://qiita.com/Saku731/items/741fcf0f40dd989ee4f8)』で記事を書きました。


そして**『②個々のパーツの作り方』**は、Pythonを勉強してきた方であれば既に習得できています。
For文・IF文や、関数・クラスを使ったプログラムが書ければ十分です。


あとは**『③秩序立てて組み上げる』ためのスキル**を習得すればシステム開発できます。
本記事では、そのために必要な２つのスキルが習得できるように進めて行きます。

**（１）『システム開発の全体像』を理解する**
**（２） システムを構成する『個々のパーツの役割』を理解する**



まず（１）をクリアするために、
**Django が採用している開発手法（MTVモデル）**を理解していきましょう。

## Djangoの「MTVモデル」とは？
Django では**MTVモデル**と呼ばれる手法が採用されています。
※Rubyなど他の言語で使われている **MVCモデル** と本質は全く同じです。

### 「MTV」の意味

MTVは**Djangoを構成する３大要素**の頭文字を取って作られました。

- M：**Model**
- T：**Template**
- V：**View**

厳密に理解する必要はないので、大まかな役割を理解しましょう。


まず前提として、システムは**「画面・処理・データ」**という３要素で作られます。
文章で表現するとこういった具合です。

- **『データ』に何らかの『処理』を加えた後、『画面』に表示する**


例えば売上データを分析するシステムを例にとってみましょう。
図の様に、ユーザー操作を起点として**「画面・処理・データ」が役割分担**しています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/c076f83c-2064-1346-d217-a688c8e2feec.png)



これをMTVモデルに当てはめてると以下の様に役割分担を整理できます。

- **View（処理）**：**中心で全体コントロール**する役割
- **Model（データ）**：**データベースを制御**する役割
- **Templage（画面）**：**画面（Webページ）を制御**する役割


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/a1d9d494-4bee-973c-eda0-d23d5fa35126.png)


つまり、**「画面」「処理」「データ」の３要素が秩序立てて連携**することで、
システムが**１個の集合体**として機能するわけです。

ーー『システム』の定義（再掲）ーー
**システム・・・多くの「データ」や、「一連の処理」を秩序立てた「プログラム」の集まり**
ーーーーーーーーーーーーーーーーー


以上で、**『(1) システム開発の全体像』**が見えてきたと思います。
※他にも説明が必要でしたらコメント欄に要望を頂けると嬉しいです。

以降では実際にプログラミングしつつ、完成品を作っていく中で
**『(2)システムを構成する個々のパーツの役割』**を理解していきましょう。


## Djangoのファイル構成
まずゴールを知るために、**Djangoで作るシステムのファイル構成（＝パーツ構成）**を整理します。
MTVモデルと紐づけつつ、**各ファイルが担っている役割**を把握しましょう。

特に混乱しやすいのが「**以下のファイルは何が違うのか？**」といった点です。

- 「`app_config/views.py` と `app_folder/views.py`」
- 「`app_config/urls.py`  と `app_folder/urls.py`」


違いとしては以下の様に整理できるのですが、最初は分割するメリットが分からないです。

- `app_config`：**システム全体**を管理する
- `app_folder`：**システム内の個々の機能**を管理する

まず必要なスキルは `app_folder` で**具体的な機能を開発するスキル**なので、
`app_config` はコピペで済ませて、**まずは動くシステムを作る**ことを前提にして進めて行きましょう。

それではファイル構成を見て行きます。


### Djangoで使用するファイル一覧
Djangoで開発を進めると最終的にこういったファイル構成になります。

今の時点では書いてある意味が理解できなくても大丈夫なので、
プログラミングの途中で**「いまは何の作業をしてるんだ？」**と迷子になった時に参照して下さい。


ーーーーーーーーー

- **`manage.py`：『管理コマンド』と呼ばれる、開発管理に必要な関数の集まり**
- **`app_config/`：全体設定に関するファイルを格納するフォルダ**
  - `views.py`：**【View】**システムを全体制御するプログラムを記述する
  - `urls.py`：使用するURLを設定する
  - `settings.py`：DB設定など、様々な設定値を管理する
- **`app_folder/`：システムに実装するプログラムを格納するフォルダ**
  - `admin.py`：管理画面の設定ファイル
  - `views.py`：**【View】**システムに実装する個々の機能を記述する
  - `urls.py`：Webページで使用するURLを設定するファイル
  - `models.py`：**【Model】**DB定義を記述する
  - `forms.py`：Webページで使用する入力フォームを設定するファイル
  - `migrations/`：DB定義の変更履歴が残るフォルダ
- **`templates/`：【Template】HTMLファイルを格納するフォルダ**
  - `base.html`：全てのWebページで共通して表示する**『外枠（サイドバー等）』**のHTML
  - `app_folder/` 
      - `top_page.html`：各Webページで表示する**『内側』**のHTML
- **`static/`：画像、cssファイル、javascriptファイルを格納するフォルダ**
  - `css/`：CSSファイルを格納するフォルダ
  - `js/`：JSファイルを格納するフォルダ
  - `images/`：画像ファイルを格納するフォルダ

ーーーーーーーーー

繰り返しになりますが、**これらのファイル（＝パーツ）が個々の役割**を担い、
それらを適切に組み上げる事で**『システム』**として全体が動作するわけです。


ーー『システム』の定義（再掲）ーー
**システム・・・多くの「データ」や、「一連の処理」を秩序立てた「プログラム」の集まり**
ーーーーーーーーーーーーーーーーー


それでは、実際に開発を進めていきます。
冒頭にお伝えした開発必須スキルのうち②③を扱っています。
※「①必要なパーツを考える」は[コチラの記事](https://qiita.com/Saku731/items/741fcf0f40dd989ee4f8)で扱ったので割愛しています。

**② 個々のパーツを作るスキル**
**③ 秩序立てて組み上げるスキル**


## Djangoの開発手順_初期設定

ここからはPythonでプログラムを書いていくので、
エディターを準備されるのをおススメします。

### 開発環境の構築
まず最初に、開発環境を整えます。
開発環境には４つの選択肢がありますが、今回は入門にベストな「**仮想環境**」を構築しましょう。
※余談ですが、仮想環境の構築に慣れた次は**コンテナ型仮想化**を勉強されると良いです。


- PCのローカルの環境：何もせず`pip install ●●`
- 仮想環境：`venv` を使う　**⇒今回はこれを使用する**
- 仮想マシン：`VirtualBox` を使う
- コンテナ型仮想化：`Docker` を使う




```
# 仮想環境を作る・フォルダ移動
$ python -m venv venv
$ cd venv
```

```
# 【Windows＆コマンドプロンプトの場合】仮想環境の起動
$ Scripts/activate.bat

# 【Windows＆GitBash の場合】仮想環境の起動
$ source Scripts/activate
※エラーになる場合は「source bin/activate」

# 【Macの場合】仮想環境の起動
$ source Scripts/activate
※エラーになる場合は「source bin/activate」
```

```
# 使用するライブラリをインストール
$ pip install Django==2.1.5
$ pip install django-bootstrap4

# DBに「MySQL」を使用する場合は以下も実行
$ pip install mysqlclient
```

```
# 開発フォルダの作成・移動
$ cd ..
$ mkdir mysite
$ cd mysite
```

### プロジェクトの開始

Djangoの開発開始する際には`startproject`を実行します。
開発に必要な設定ファイル一式が自動的に作成されます。

`app_config`の部分は任意の名称が使えるので、慣れた頃に変更されてみて下さい。
※**全体設定に関するファイル**を格納するフォルダ名に使用されます。

```
$ django-admin startproject app_config .
```

処理が完了すると以下の様なフォルダ構成になります。
※以下に書いてないファイルは無視してOKです。

- **`app_config/`：全体設定まわりのファイルを格納するフォルダ**
    - `settings.py`：DB設定など、様々な設定値を管理するファイル
    - `urls.py`：使用するURLを設定するファイル
- `manage.py`：システム管理に必要な関数が記述されているファイル

### 設定ファイル
ではさっそくDjango全体の設定を行って行きましょう。
はずは `app_config/setting.py` の１番下にある `LANGUAGE_CODE` と `TIME_ZONE` を修正します。
※使用する言語・タイムゾーンを指定する項目です。


```python:app_config/settings.py
# 言語・タイムゾーン設定など
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
```



また、Djangoはデフォルトで **SQLite** をサポートしているので、初期設定のままでもDBが使用できます。
もし **MySQL** を使用する場合には以下の様に `app_config/settings.py` の `DATABASES` を変更します。

```python:app_config/settings.py
# DATABASEを以下の様に変更
DATABASES = {
    'default': {
        'ENGINE':'django.db.backends.mysql',
        'NAME':'●●(データベース名)',
        'USER':'●●（DBのユーザー名）',
        'PASSWORD':'●●（DBのログインPass）',
        'HOST':'localhost',
        'PORT':'',
    }
}
```

### データベース準備（マイグレーション）
このタイミングで下記のコマンドを実行しましょう。
上手く処理が完了すると Django の開発に最低限必要なデータベースが整います。

```
$ python manage.py migrate
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/3c081044-2879-1ea7-b9a3-e43df58fad20.png)


### システムを起動してみる

ここまでの設定が問題なく進んでいるか確認するためにシステムを起動してみましょう。

```
$ python manage.py runserver
```

その後、ブラウザから `http://localhost:8000` にアクセスしてみましょう。
以下の様な画面になったら成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/157792ad-59dd-bf71-c797-3162f42e08a0.png)


確認できたら `Ctrl + c（MacはCommand + c）` でシステムを停止させておきます。

### アプリケーション関連ファイルの作成
続いて具体的なWebアプリケーションの機能を開発して行きます。
以下のコマンドを実行しましょう。

`app_folder`の部分は任意の名称が使えます。
※開発に慣れるまでは変更しない方が良いです。

```
$ python manage.py startapp app_folder
```

実行すると `app_folder` と名前の付いたフォルダが作成され、
その直下に様々なファイルが作成されます。※以下に書いてないファイルは無視してOKです。


- **`app_folder/`：システムに実装するプログラムを格納するフォルダ**
    - `admin.py`：システムの管理画面を設定するファイル
    - `models.py`：【Model】DB定義を記述する
    - `views.py`：【View】システムの裏側で走らせるプログラムを記述する


### 設定ファイルにアプリを登録する

ここで注意が必要で、`app_folder/`フォルダを作成するだけでは
システムを全体管理している `app_config/` から認識されません。

そこで `app_config/settings.py` の `INSTALLED_APPS` に登録が必要です。
`INSTALLED_APPS` はシステム内で使用するアプリケーションを登録するための項目です。
※最初は理解しなくても良いので、コピペで済ませていきましょう。

登録する名称は３つの要素を組み合わせて作ります。

1. 先ほど指定したアプリ名 `app_folder`
2. `apps`
3. `app_folder/apps.py` 内のクラス名 `AppFolderConfig`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/e1e6c5f7-d8ef-24cc-1142-8cae93bc9f69.png)


この３つを組み合わせて「`app_folder.apps.AppFolderConfig`」を追加します。
これでDjango内部で今から開発するアプリケーションが認識されます。

```python:app_config/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app_folder.apps.AppFolderConfig', # この１行を追加
]

```

### HTML/CSS に関するフォルダを準備

続いて、HTML/CSS に関するフォルダを準備しておきましょう
`manage.py` と同じ階層に以下のようにフォルダ・ファイル作成します。

- **`templates/`：【Template】HTMLファイルを格納するフォルダ**
    - `base.html`
    - `app_folder/`
        - `top_page.html`
- **`static/`：画像、cssファイル、javascriptファイルを格納するフォルダ**
    - `css/`
    - `js/`
    - `images/`

作成が終わった後、以下のファイル構成になればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/d5b5e685-9d94-a097-0cf7-9888358f78b0.png)


### 静的ファイルのアクセス設定

`app_config/settings.py` の１番下に静的ファイル(画像ファイルなど)に関する変数を追加します。
この設定を済ませると**HTMLファイルへの画像挿入**や、**CSS, JavaScriptに関する作業**が楽になります。

```python:app_config/settings.py
# 静的ファイルの呼び出し設定を１番下に追加
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 
PROJECT_NAME = os.path.basename(BASE_DIR)
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] 
STATIC_ROOT = '/var/www/{}/static'.format(PROJECT_NAME)
```

同じく `app_config/setting.py` の中段付近にある `TEMPLATES` の２行目 `DIRS` を変更します。 
これによって **`templates/` フォルダに格納したHTMLファイルがシステム上で認識される**ようになります。

```python:app_config/settings.py
# TEMPLATESに１行追加（テンプレートの呼び出し設定）
TEMPLATES = [ 
    { 
        'BACKEND': 'django.template.backends.django.DjangoTemplates', 
        'DIRS': [os.path.join(BASE_DIR, 'templates')], #この行を追加
        'APP_DIRS': True, 
        'OPTIONS': { 'context_processors': [ 
            'django.template.context_processors.debug', 
            'django.template.context_processors.request', 
            'django.contrib.auth.context_processors.auth', 
            'django.contrib.messages.context_processors.messages', 
            ], 
        }, 
    }, 
]

```

### メディアファイルのアクセス設定
※ここは本記事では扱わないですが、いずれ役に立つので作っておきましょう※

同じく `settings.py` の一番下に、こちらのコードも追加しておきましょう。
この設定が必要となるケースとしては以下の様な場合です。

- 画像など**ファイルをアップロード**する機能
- **アップしたファイルをコンテンツとしてWeb画面に表示**する機能
- CSVなどの**ファイルをダウンロード**する機能

※実務ではAWSの `S3` と呼ばれるクラウド上のストレージを使用する事が多いですが今は意識されなくて大丈夫です。

```python:app_config/settings.py
# メディアファイルに関する設定
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
```

設定が終わったら `manage.py` と同じ階層に `media/` フォルダを作成します。
ここにメディアファイルをアップロードしていく流れになります。
※ ファイルのアップローダーを作る際には[【参考資料】](https://narito.ninja/blog/detail/92/)を確認されると良いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/af765484-ef5f-5ca6-2d31-7918ca8592d1.png)


### ベーステンプレートの作成
続いてシステムの画面に表示させるHTMLファイルを作っていきましょう。
１つポイントとして、皆さん**Bootstrap** をご存知でしょうか？

**「頑張って CSS を勉強したのにキレイな画面が作れない。。」**

こんな悩みを解決するためにTwitter社が開発した **Bootstrap** が有効です。
**デザインの知識が無くてもお洒落なサイトを作れる**優れものです。
※詳しく知りたい方は[【Bootstrap参考記事】](https://techacademy.jp/magazine/6270)をご覧ください。


`BootStrap` を使用するための設定はとてもシンプルです。
`app_config/settings.py` の `INSTALLED_APPS` に`bootstrap4` を追加すればOKです。

```python:app_config/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app_folder.apps.AppNameConfig',
    'bootstrap4', # この１行を追加
]
```

それでは続いてHTMLファイル（**ベーステンプレート**）を作成して行きましょう。
テンプレートは**２種類に分けてコーディング**すると記述するコード量を少なくすることが出来ます。

- ①全ページに共通する**「外側」**の部分：`templates/base.html`
- ②個々のページで表示する**「内側」のコンテンツ**：`templates/app_folder/top_page.html` など

図で表現すると以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/185c081d-6adf-959a-1826-658882e5c6d3.png)


まずは**「①外側」**のベーステンプレートを準備してきます。
ある程度の使用に耐えるデザインを作っておいたので、コピーしてそのまま使用されて下さい。

なお、だいぶ下の方にある**『↓↓コンテンツ本体↓↓』**の部分に、
**「②内側」**のコンテンツとなるHTMLファイルが反映される仕組みになっています。

```html:template/base.html
<!DOCTYPE html>

{% load bootstrap4 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='slim' %}
{% load static %}

<html lang="ja">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" type='text/css' href="{% static 'css/style.css'%}">
    <link rel="stylesheet" href="https://cccabinet.jpn.org/bootstrap4/css/style.css">
    <title> Django開発サンプル </title>

    {% block extra_css %}{% endblock %}

</head>

  <body>
    <!-- ↓↓１番上のナビゲーションバー↓↓ -->
    <div class="container-fluid">
      <div class="row">
        <div class="col-12">
          <nav class="navbar navbar-expand-lg fixed-top navbar-dark bs-navbar" style='background-color:cadetblue;' id="bs-navbar">
            <a class="navbar-brand mr-md-2" href="/app_folder/top_page">
              サンプル開発画面
            </a>
              <!-- ↓↓レイアウトを調整する為のダミー↓↓ -->
              <ul class="navbar-nav mr-auto">
                <li class="nav-item"><a class="nav-link" href="#">   </a></li>
                <li class="nav-item"><a class="nav-link" href="#">   </a></li>
              </ul>
              <!-- ↑↑ダミーここまで↑↑ -->                            

              <ul class="navbar-nav">
                <li class="nav-item"><a class="nav-link" href="/#" >サンプル１</a></li>
                <li class="nav-item"><a class="nav-link" href="/#" >サンプル２</a></li>
                <li class="nav-item"><a class="nav-link" href="/#" >サンプル３</a></li>
                <li class="nav-item"><a class="nav-link" href="/accounts/login" >ログイン</a></li>
                <li class="nav-item"><a class="nav-link" href="/accounts/logout" >ログアウト</a></li>
              </ul>
            </div>
          </nav>
        </div>
      </div>
    </div>


    <!-- 「サイドバー」と「コンテンツ本体部分」 -->
    <div id="content" class="container-fluid">
      <div class="row flex-xl-nowrap">

        <!-- ↓↓サイドバー↓↓ -->
        <div id="sidemenu" class="col-2 d-none d-md-block bg-light sidebar align-self-start">
          <div class="sidebar-sticky">
            <ul class="nav flex-column">

              <li class="nav-item">
                <nav class="navbar navbar-light bg-light">
                  <a class="navbar-brand" href="/#">
                    <span data-feather=""></span>Topページ 
                  </a>
                </nav>
              </li>
              <li class="nav-item">
                <nav class="navbar navbar-light bg-light">
                  <a class='navbar-brand' href='/#'>
                    <span data-feather=""></span>サイドバー１
                  </a>
                </nav>
              </li>
              <li class="nav-item">
                <nav class="navbar navbar-light bg-light">
                  <a class='navbar-brand' href='/#'>
                    <span data-feather=""></span>サイドバー２
                  </a>
                </nav>
              </li>         
              <li class="nav-item">
                <nav class="navbar navbar-light bg-light">
                  <a class='navbar-brand' href='/#'>
                    <span data-feather=""></span>サイドバー３
                  </a>
                </nav>
              </li>         
              <li class="nav-item">
                <nav class="navbar navbar-light bg-light">
                  <a class='navbar-brand' href='/#'>
                    <span data-feather=""></span>サイドバー４
                  </a>
                </nav>
              </li>         
              <li class="nav-item">
                <nav class="navbar navbar-light bg-light">
                  <a class='navbar-brand' href='/#'>
                    <span data-feather=""></span>サイドバー５
                  </a>
                </nav>
              </li>         
            </ul>
          </div>
        </div id="sidemenu">
        <!-- ↑↑サイドバーここまで↑↑ -->

        <!-- ↓↓コンテンツ本体↓↓ -->
        <div class="col-10">
          {% block contents %}
          {% endblock %}
        </div>
        <!-- ↑↑コンテンツ本体ここまで↑↑ -->
      </div>
    </div>
    </div>
  </body>
</html>

<!-- サイドバーに使用しているアイコン -->
<!-- 使用できるアイコンの一覧： https://voyager-jp.com/blog/javascript/feather/ -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/feather-icons/4.9.0/feather.min.js"></script>
<script>feather.replace()</script>
```

### 各テンプレートの作成
ベーステンプレートを作成した後は**「内側」のコンテンツ**となるHTMLファイルを作成します。
後ほどコンテンツを追加して行くので、まずは以下をコピーしてファイル作成しておきましょう。  


```html:templates/app_folder/top_page.html
{% extends 'base.html' %}
{% block contents %}

<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center mt-5 border-bottom">
    <h1 class="h2">トップページ</h1>
</div>

<div>
    <h4>ここにコンテンツを記述する</h4>
</div>

{% endblock %}
```

なお１点だけポイントがあり、先頭と末尾に記述している３ヵ所の `{% ~ %}` があることで
ベーステンプレートに**『「内側」のコンテンツ部分』**を挿入できる仕組みになっています。
※なので、間違っても消さないようお気を付けください。

- `{% extends 'base.html' %}` 
- `{% block contents %}` 
- `{% endblock %}` 


以上でテンプレートの準備は終了です。

Template（HTMLファイル）を作成するだけでは画面に何も表示できないので、
続いてシステム内部のコントロールを担うViewを作成して行きましょう。


### システム内部をコントロールするViewを作成
冒頭でお伝えしたとおり、Viewには２種類あります。

- `app_config/views.py`：**全体を大まかに**コントロールする
- `app_folder/views.py`：**個々の機能**をコントロールする


まずは簡単な方から `app_config/views.py` を作成していきます。
`app_config` フォルダ内に`views.py`を作って、中身は以下の様に記述します。

```python:app_config/views.py
from django.shortcuts import render, redirect, reverse  
from django.views import View  
  
class index(View):
    def get(self, request, *args, **kwargs):
        return redirect(reverse('app_folder:top_page'))
index = index.as_view()
```

これは、**「システムにアクセスがあればトップページに飛ばす」**といった設定です。
毎回同じように書いておけば大丈夫です。


続いてシステムの具体的な機能をコントロールする `app_folder/views.py` を開いて以下をコピーします
これは「トップページにアクセスされたら`top_page.html`を表示する」機能を書いています。



```python:app_folder/views.py
from django.shortcuts import render  
from django.views import View  
  
class SampleView(View):  
	def get(self, request, *args, **kwargs):  
		return render(request, 'app_folder/top_page.html')
top_page = SampleView.as_view()
```

いったん最低限のViewが作成できたので先に進んでいきましょう。
※具体的な機能は後ほどプログラムを追加します。


### URLディスパッチャの作成

ここではWeb画面からシステムにアクセスする際に必要なURLを設定します。
たとえば `http://localhost:8000/my_app/top_page` といったように `https://` 以下を自由に決める事ができます。
※「!」「?」など特殊文字は使わない制限はありますが、**小文字**や**アンダーバー**であれば問題ないです。

変更すべきファイルは２種類あります。

- `app_config/urls.py`：システム全体のURL設計
- `app_folder/urls.py`：個々のアプリ内のURL設計

２つの関連性としては、URLを構成する順番に影響しており、
**http://localhost:8000/＜app_config/urls.pyのURL設定＞/＜app_folder/urls.pyのURL設定＞**
こういった順番でURLが構成されます。

まず `app_config/urls.py` です。

```python:app_config/urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from . import views

# URLの全体設計
urlpatterns = [
    # 今回作成するアプリ「app_folder」にアクセスするURL
    path('app_folder/', include('app_folder.urls')),
    # 何もURLを指定しない場合（app_config/views.pyで、自動的に「app_folder」にアクセスするよう設定済み）
    path('', views.index, name='index'),
    # 管理サイトにアクセスするURL
    path('admin/', admin.site.urls),
]

# メディアファイル公開用のURL設定
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
```

続いて `app_folder/` フォルダの中に `urls.py` を作成して以下の様に記述します。

まだトップページ（`top_page/`）しか用意していないので `urlpatterns` は１行ですが、
色々な機能を追加していくごとに登録するURLが増えていきます。


```python:app_folder/urls.py
from django.urls import path
from . import views

app_name = 'app_folder'
urlpatterns = [
    path('top_page/', views.top_page, name='top_page')
]
```

なお、理解しておくべき事項として、
**http://localhost:8000/＜app_config/urls.pyのURL設定＞/＜app_folder/urls.pyのURL設定＞**

こちらのURL設定のルールに従うと、トップページにアクセスするURLは
**http://localhost:8000/app_folder/top_page**
といったようになります。これがURLディスパッチャの仕組みです。

### システムを起動してみる
それでは、一式の設定が揃ったのでシステムを起動しましょう。

```
$ python manage.py runserver
```


何も問題なければターミナルが以下の様な表示になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/2ed2b5ed-f907-47ad-e86f-af68fcd330c6.png)


続いて、ブラウザを起動させて `http://localhost:8000/app_folder/top_page` をアクセスしてみましょう。

以下のような画面が表示されれば成功で、サンプル文字で仮入力されている部分に
**皆さん自身でコンテンツを追加していく**ことで様々なサービスをつくる事ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/ef688a2b-4274-f03c-4a47-28ccb1b6e71e.png)



初期設定が終わったので、以降で簡単な機能を１つだけ追加してみましょう。

## Djangoの開発手順_追加機能を開発
Web画面に表示された**入力フォームから検索条件**を受け取って、
**データベースに保存されているデータを呼び出す**追加機能を開発してみましょう。

処理の流れとしては以下です。

- 画面に入力フォームを表示させる
- ユーザーが入力した検索条件を受け取る
- 検索条件をもとに、データベースから情報を取りだす
- 取り出した情報を画面に表示する


### データベース構築
まず、データを保存するためのデータベースを定義しましょう。

`models.py` を理解するためには**データベースの知識も必要**となってくるので、
本記事を勉強した後に何らかのDjango入門書で詳しく勉強されることをおススメします。

```python:app_folder/models.py
from django.db import models

class SampleDB(models.Model):
    class Meta:
        db_table = 'sample_table' # DB内で使用するテーブル名
        verbose_name_plural = 'sample_table' # Admionサイトで表示するテーブル名
    sample1 = models.IntegerField('sample1', null=True, blank=True) # 数値を格納
    sample2 = models.CharField('sample2', max_length=255, null=True, blank=True) # 文字列を格納
```

続いて以下のコマンドを実行して設定内容をDBへ反映させます。

```
$ python manage.py makemigrations
$ python manage.py migrate
```

ターミナルにこのように表示されれば成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/bf589604-8060-957a-f5b2-e52bbdc33e0d.png)



### 管理者ユーザー登録
データベースの設定が終わったら、システムを管理するユーザーを登録しましょう。
まず以下のコマンドを入力します。

```
$ python manage.py createsuperuser
```

続いて以下の順番で質問されるので順番に入力して行きます。
パスワードはセキュリティの都合で、タイピングしても何も表示されませんが大丈夫です。
（最初はビックリしますが気になさらず）

- ユーザ名
- メールアドレス
- パスワード（１回目）
- パスワード（確認用）



入力後、`Superuser created successfully.` と表示されれば管理者ユーザー登録の成功です。



### 管理サイト構築
管理者のユーザー登録まで終わったら **管理サイト** を作ってみましょう。

管理サイトとは、、

- 本来であればDBを操作するには**MySQL**など覚える必要がある
- Python（Django）でも精一杯なのにMySQLなんて無理。。
- そんなあなた、**管理サイトから画面上でDBを操作**しましょう！

といった便利なWebサイトですので、言葉で理解するよりもまずはDBを操作する様子を体感しましょう。
さっそく管理サイトを作成するための設定を行います。

```python:app_folder/admin.py
from django.contrib import admin
from .models import SampleDB # models.pyで指定したクラス名

admin.site.register(SampleDB) # models.pyで指定したクラス名
```



これで管理サイトの設定が完了です。
以下のコマンドを実行した後に`localhost:8000/admin` にアクセスしましょう。

```
$ python manage.py runserver
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/b6907813-e430-3034-1ff8-c52a03c13bb3.png)


先ほど作成したユーザー名・パスワードでログインした後、
こういった画面が表示されれば成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/f9884b06-e8fc-447d-93ec-885da5320162.png)



試しにデータベースへの登録を行ってみましょう。
３ステップで登録が完了します。

- ①：`Samplle_table` をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/702104cd-ff32-f7f2-b809-c56eb2595c93.png)


- ②：`SAMPLE_DBを追加`をクリック 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/a8934dc6-3ef6-1658-e048-c033fce43b91.png)


- ③：項目を埋めて「保存」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/9ac8fed9-d9a1-68cd-b070-18d18cdeb167.png)


以上でデータベースへの登録が完了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/f8f23516-9e61-cd72-52e5-4897fe389346.png)


### View・テンプレートの変更
データベースに情報を登録で来たので、データを取得してみましょう。
その後、Web画面にデータを表示させる流れで進めます。

- 画面の入力フォームから検索条件を受け取る
- 検索条件をもとに、DBからデータを取得
- 取得したデータをテンプレート（画面）に渡す


**【画面の入力フォームから検索条件を受け取る】**
まず、入力フォームを作る為に `page01.html` を作成します。

```html:templates/app_folder/page01.html
{% extends 'base.html' %}
{% block contents %}

<h4 class="mt-5 mb-4 border-bottom">検索条件を入力</h4>
<form  action="{% url 'app_folder:top_page' %}" method="post">
<div class="container-fluid">
  <div class="row">
    <div class="col-2">
      <input class="form-control" type="text" name="input_data" maxlength="255">
    </div>
    <div class="col-2">
      <div class="text-left align-bottom">
          <button type="submit" name="button" class="btn btn-info">
            検索
          </button>
      </div>
    </div>
  </div>
</div>
{% csrf_token %}
</form>

{% endblock %}
```

**【検索条件をもとに、DBからデータを取得】**
続いて、入力フォームからデータを受け取るために `views.py` を編集
※元々の内容はすべて削除して、以下を新しく貼り付けた方が良いです。

```python:app_folder/views.py
from django.shortcuts import render  
from django.views import View  
from .models import SampleDB

class SampleView(View):  
	def get(self, request, *args, **kwargs):  
		return render(request, 'app_folder/page01.html')

	def post(self, request, *args, **kwargs):  
		input_data = request.POST['input_data']
		result = SampleDB.objects.filter(sample1=input_data)
		result_sample1 = result[0].sample1
		result_sample2 = result[0].sample2
		context={'result_sample1':result_sample1, 'result_sample2':result_sample2}
		return render(request, 'app_folder/page02.html', context=context,)
		
top_page = SampleView.as_view()
```

**【取得したデータをテンプレート（画面）に渡す】**
そして最後に、DBから取得したデータを表示する為の `page02.html` を新たに作成します。

```html:templates/app_folder/page02.html
{% extends 'base.html' %}
{% block contents %}

<h4 class="mt-5 mb-4 border-bottom">DB検索結果を表示</h4>
<div class="container-fluid">
  <div class="row">
    <div class="col-4">
      <p>sample1：{{result_sample1}}</p>
      <p>sample2：{{result_sample2}}</p>
    </div>
  </div>
</div>

{% endblock %}
```

### 動作確認
ここまで済んだら、もう一度システムを起動して 
`http://localhost:8000/app_folder/top_page/` にアクセスしましょう。

```
$ python manage.py runserver
```

こういった画面になれば上手くいってます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/e782d1ee-1d31-b646-5488-67395b9f0540.png)



入力フォームに**「1」**と入力して検索ボタンをクリックした後、
先ほどデータベースに登録した**「サンプル１個目」**が表示されれば成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/285120f6-f438-7b76-2be2-f7e973fc4dab.png)



以上でDjangoの初期設定と簡単な機能追加の一連手順は完了です。
**このファイル一式がDjango開発のベース**になるので保存して大事にとっておきましょう。

## さいごに

本記事ではシステム開発における５つの課題を整理したあと、
図などを交えて（１）（２）を扱いました。
ーーーーーーーーー
（１） システム開発の全体像が見えていない
（２） システムを構成する個々のパーツの役割が見えていない
（３） 開発にチャレンジできる基礎が身に付いていない
（４） アイディアからシステム設計を考えるスキルが身に付いてない
（５） 何を作るか？（アイディア）が出てこない
ーーーーーーーーー

そして、**システムの定義**についても整理したうえで、
必要スキル３つのうち②③を実際にプログラミングを通じて理解できたと思います。
ーーーーーーーーー
**システム・・・多くの「データ」や、「一連の処理」を秩序立てた「プログラム」の集まり**

必要スキル：
① 開発に必要なパーツを考えるスキル
② 個々のパーツを作るスキル
③ 秩序立てて組み上げるスキル
ーーーーーーーーー


なお、**「まずは動くものを作る」**といった方針で書いたので説明を省略した部分もあります。
分からなかった部分は手元にある入門書やチュートリアルで補うようにされて下さい。


記事を読んでいただいた皆さんが良いサービスを開発されることを願っております。
最後までお読みいただきありがとうございました。

タイトルの通り**「入門編」**として書いた記事なので、続編もご期待ください。


**【P.S.】**
SNS でも色々な情報を発信しているので、記事を読んで良いなと感じて頂けたら
 [Twitterアカウント「Saku731」](https://twitter.com/digisaku710) もフォロー頂けると嬉しいです。