ホーム >  Python >  VagrantのDjangoで作るWebアプリケーション(その3 アプリケーション・モデルの作成)

投稿日:   |  最終更新日:

VagrantのDjangoで作るWebアプリケーション(その3 アプリケーション・モデルの作成)

Python

Vagrantの中に構築したDjangoプロジェクトに、アプリケーションとモデルを作成します。

Djangoのモデルとは?

Djangoで言う「モデル」とは、サイトを構成するデータの唯一絶対的なデータソースです。モデルには、保存したいデータを表すデータフィールドと、データのビヘイビア(動作)を定義します。通常、一つのモデルは一つのデータベーステーブルに対応します。

モデルの基本

モデルの基本として、以下のような特徴があります。

  • 各モデルはPythonのクラス。
  • 各モデルはdjango.db.models.Modelのサブクラス。
  • モデルの各アトリビュート(属性)の値は、データベース上のあるフィールドを表現する。
  • モデルの情報をもとに、 DjangoはデータベースAPIを自動生成する。

作業の流れ

  1. 前回作成したプロジェクトに、startappコマンドでDjangoアプリケーションを生成します。
  2. モデルを定義します。定義したらmodels.pyを編集します。
  3. settings.pyを編集し、makemigrationsコマンドでSQL文を発行します。
  4. migrateコマンドで発行したSQL文を実行します。この時点でデータベースを更新します。
  5. admin.pyを編集し、アプリケーション用テーブルを登録します。
  6. 管理サイトを立ち上げ、試しにテーブルを追加してデータを登録します。
  7. models.pyにstr関数を追加し、管理サイト上に登録した情報を出力します。
  8. admin.pyを編集し、管理サイト上にフィールド情報も表示します。

モデルを変更するには?

  1. models.pyを編集します。
  2. makemigrationsコマンドでSQL文を発行します。
  3. migrateコマンドで発行されたSQL文を実行します。
  4. 1〜3を繰り返します。

準備

Vagrantでゲスト環境(仮想環境)を作ります。ゲスト環境の中にDjangoを構築します。その前に、以下の作業を終わらせましょう。

①Virtualboxをインストールします。Virtualboxのインストールまでで結構です。

VirtualBoxをインストールする for Ubuntu

②Vagrantをインストールします。centos7環境を作りますので、Vagrantのインストールのみ済ませてください。

Vagrantをインストールしてテスト環境を作る for Ubuntu

③Vagrantにcentos7環境を作ります。

VagrantでCentOS7 + Python + Django環境を作る(その1 仮想環境作成)

④VagrantにPython3をインストールし、「pyenv + virtalenv」を作ります。

VagrantでCentOS7 + Python + Django環境を作る(その2 Pythonとpyenv + virtalenv)

⑤VagrantにMariaDBをインストールして、DBを構築します。

VagrantでCentOS7 + Python + Django環境を作る(その3 MariaDB)

⑥VagrantにWebアプリケーションサーバーのnginxをインストールします。

VagrantでCentOS7 + Python + Django環境を作る(その4 nginx)

⑦VagrantにDjangoをインストールします。

VagrantでCentOS7 + Python + Django環境を作る(その5 Django + uWSGI)

⑧VagrantにDjangoプロジェクト生成します。

VagrantでDjangoで作るWebアプリケーションを作る(その1 プロジェクト生成)

⑨生成したプロジェクトを初期設定します。また、データベースを初期化します。

VagrantでDjangoで作るWebアプリケーションを作る(その2 プロジェクトの初期設定)

ホスト環境

OS Ubuntu 16.04.1 LTS 64bit
Virtualbox 5.1
Vagrant 1.9.5

ゲスト環境

OS CentOS 7.1.1503
Python 3.6.1
pip 9.0.1
Web フレームワーク Django 1.11.2
データベース MariaDB 5.5.52-1.el7.x86_64
Webサーバ nginx 1.13.2

Vagrantへログイン

①【ホスト環境】端末を開き、前回構築したVagrantのディレクトリまで移動します。

cd vagrant/django_apps/

②【ホスト環境】仮想マシンを起動します。

vagrant up

③【ホスト環境】ログインします。

vagrant ssh

firewall停止

①デフォルトで用意されているindex.htmlにHTTPアクセスできるか確認するため、firewalldを停止状態にします。

sudo systemctl stop firewalld
sudo systemctl disable firawalld

pyvenvで作成した仮想環境にログイン

前回、pyenvで仮想環境「venv_app1」を作成しました。ここにログインします。

①【ホスト環境】Vagrantの中の「venv_app1」ディレクトリまで移動します。

cd /vagrant/django_apps/venv_app1/

②【ゲスト環境】「venv_app1」を有効化します。

source ./bin/activate

以下のようなプロンプトが表示されれば有効化成功です。

(venv_app1) [vagrant@localhost venv_app1]$ 

Djangoアプリケーションを生成

①以下のディレクトリに移動します。

cd /vagrant/django_apps/pj1/

②「app1」というアプリケーションを生成します。

python manage.py startapp app1

アプリケーションを生成すると、pj1ディレクトリ配下に、さらにapp1ディレクトリが作成されます。

  • pj1/
  • app1/
  • __init__.py
  • admin.py
  • migrations/
  • __init__.py
  • models.py
  • tests.py
  • views.py
  • manage.py
  • pj1/
  • __init__.py
  • _pycache__
  • __init__.cpython-36.pyc
  • settings.cpython-36.pyc
  • urls.cpython-36.pyc
  • wsgi.cpython-36.pyc
  • settings.py
  • urls.py
  • wsgi.py
  • 「/django_apps/pj1/app1/」ディレクトリ配下のファイル群がDjangoアプリケーション固有の設定ファイルです。

モデルを定義する

アプリケーションの中身を作っていきます。まずモデルを定義し、データベースのテーブル構造を定義します。

テーブル構造を定義するには?

Djangoでは、アプリケーションごとのディレクトリ配下(ここではapp1)のmodels.pyを修正し、テーブルをClass、フィールドを変数として定義していきます。

モデル要件

IPアドレスを管理するアプリケーションをつくります。以下のサイトを参考にさせていただきました。

Python3.4 + Djangoで作るWebアプリケーション(Part.2 アプリ開発編)

以下のようなモデルを定義します。

IPアドレスの利用状況を管理するアプリケーション
IP addressテーブル
IP addressフィールド
  • 所有するIPv4アドレス群を示します。
  • ネットワークセグメントは無視して、/32のアドレス単体を管理します。
  • 値は一意です。
Statusフィールド
  • IPアドレスの利用状況のステータスを保持します。
  • 「in_use」「 avalable」「not_available」の3つの状態を持ちます。
  • ブランクの状態は許可しません。
Descriptionフィールド
  • IPアドレスの利用状況についてのメモを保存します。
  • 自由に記述できます。
  • ブランクの状態を許可します。

models.pyの編集

①「pj1/app1/models.py」を編集します。

vi pj1/app1/models.py

モデル要件を満たすため、以下の記述を加えます。

from django.db import models

# Create your models here.

from django.db import models

class Ipaddress(models.Model):

    status_list = (
        ('in_use', 'in use'),
        ('available', 'available'),
        ('not_available', 'not available')
    )
    ipaddress = models.GenericIPAddressField(verbose_name='IP address', unique=True)
    status = models.CharField(verbose_name='Status', choices=status_list, max_length=16)
    description = models.CharField(verbose_name='Discription', blank = True, max_length=255)

status_listという状態候補を用意することで、管理サイトやWebアプリケーションからプルダウンメニューでの選択を指定することができます。

モデル定義を有効化

Djangoプロジェクト(/django_apps/pj1/)に対して、「app1」のモデル定義を有効化します。

プロジェクトにアプリケーションを追加するため、構成クラスへの参照を「INSTALLED_APPS」に追加する必要があります。App1Configクラスは、「pj1/app1/apps.py」にあります。ドットでパスを繋ぐと’app1.apps.App1Config‘となります。 「pj1/pj1/settings.py」を編集し、 INSTALLED_APPSにドットで繋がれたパスを追加してください。

view pj1/app1/apps.py
from django.apps import AppConfig


class App1Config(AppConfig):
    name = 'app1'

①「pj1/pj1/settings.py」を編集します。

vi pj1/pj1/settings.py

「INSTALLED_APPS」に追記します。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    #アプリケーション名を追記
    'app1.apps.App1Config'
]

ESCを押して、「:wq」で保存終了します。

django.contrib.admin 管理(admin)サイト。
django.contrib.auth 認証システム
django.contrib.contenttypes コンテンツタイプフレームワーク
django.contrib.sessions セッションフレームワーク
django.contrib.messages メッセージフレームワーク
django.contrib.staticfiles 静的ファイルの管理フレームワーク

②モデル定義をデータベースに反映します。以下のコマンドでデータベースとの差分内容をSQL文にして発行します。

python pj1/manage.py makemigrations app1

※この時点ではSQLの実行はされていません。

Migrations for 'app1':
  pj1/app1/migrations/0001_initial.py
    - Create model Ipaddress

③発行されたSQL文は下記コマンドで確認できます。

python pj1/manage.py sqlmigrate app1 0001

SQL文。

BEGIN;
--
-- Create model Ipaddress
--
CREATE TABLE `app1_ipaddress` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `ipaddress` char(39) NOT NULL UNIQUE, `status` varchar(16) NOT NULL, `description` varchar(255) NOT NULL);
COMMIT;

④以下のコマンドで発行されたSQL文を実行します。

python pj1/manage.py migrate

※この時点でデータベースが更新されます。

ん?「WARNINGS:」が出てしまいました。

System check identified some issues:

WARNINGS:
?: (mysql.W002) MySQL Strict Mode is not set for database connection 'default'
	HINT: MySQL's Strict Mode fixes many data integrity problems in MySQL, such as data truncation upon insertion, by escalating warnings into errors. It is strongly recommended you activate it. See: https://docs.djangoproject.com/en/1.11/ref/databases/#mysql-sql-mode
Operations to perform:
  Apply all migrations: admin, app1, auth, contenttypes, sessions
Running migrations:
  Applying app1.0001_initial... OK

翻訳してみると、

MySQL Strictモードがデータベース接続 ‘default’に設定されていません。
ヒント:MySQLの厳密モード(Strict Mode)は、挿入時のデータ切り捨てなど、多くのデータ整合性の問題を警告します。

⑤「settings.py」の「DATABASES =」を修正します。

vi pj1/pj1/settings.py

以下のページを参考に修正しました。

django_mysql.W002:

修正前

DATABASES = {
    'default': {
       # 'ENGINE': 'django.db.backends.sqlite3',
       # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

       # 作成したデータベース情報を追記
       'ENGINE': 'django.db.backends.mysql',
       'NAME': 'app1_db',
       'USER': 'app1_user',
       'PASSWORD': 'app1_passwd',
       'HOST': 'localhost',
       'PORT': '3306',
    }
}

修正後

DATABASES = {
    'default': {
       # 'ENGINE': 'django.db.backends.sqlite3',
       # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

       # 作成したデータベース情報を追記
       'ENGINE': 'django.db.backends.mysql',
       'NAME': 'app1_db',
       'USER': 'app1_user',
       'PASSWORD': 'app1_passwd',
       'HOST': 'localhost',
       'PORT': '3306',
       'OPTIONS': {
           'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
       },
    }
}

これでモデル定義を編集してmigrateしても「WARNINGS:」がでません。

⑥MariaDBを確認します。

mysql -u app1_user -papp1_passwd

新たにテーブル「app1_ipaddress 」が追加されたことが確認できます。

MariaDB [(none)]> USE app1_db;
MariaDB [app1_db]> SHOW TABLES;
+----------------------------+
| Tables_in_app1_db          |
+----------------------------+
| app1_ipaddress             |
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
11 rows in set (0.00 sec)

以降、モデルを編集した場合

models.pyを編集するたびに「python pj1/manage.py makemigrations app1」「python pj1/manage.py migrate」の2つのコマンドを実行し、DBを変更します。

アプリケーション用テーブルを登録

データベースの更新が完了しました。しかし、現時点では管理サイト上にapp1用のテーブルは追加されていません。

①管理サイトで管理するため、app1ディレクトリ配下のadmin.pyを編集します。

vi pj1/app1/admin.py

以下のように変更します。

from django.contrib import admin

# Register your models here.

# 追記
from app1.models import Ipaddress

# 追記
admin.site.register(Ipaddress)

ESCを押し、「:wq」で保存終了します。

②簡易Webサーバを立ち上げます。

python pj1/manage.py runserver 0.0.0.0:8000

③ホスト環境のブラウザから、以下のURLを入力します。

http://192.168.33.15:8000

※「192.168.33.15」は、vagrantに設定したipアドレスです。

④「Ipaddresss」のリンク→「IPADDRESSを追加」を開きます。管理サイトにapp1のテーブル情報が表示されます。

⑤以下のデータを登録します。

No IP address Status Discription
データ1 192.168.0.0 not_available Network address
データ2 192.168.0.1 available
データ3 192.168.0.2 available

⑥管理サイト上に登録した情報を出力させる場合は、models.pyにstr関数を追加します。

vi pj1/app1/models.py
from django.db import models

# Create your models here.

from django.db import models

class Ipaddress(models.Model):

    status_list = (
        ('in_use', 'in use'),
        ('available', 'available'),
        ('not_available', 'not available')
    )
    ipaddress = models.GenericIPAddressField(verbose_name='IP address', unique=True)
    status = models.CharField(verbose_name='Status', choices=status_list, max_length=16)
    description = models.CharField(verbose_name='Discription', blank = True, max_length=255)

    def  __str__(self):
        return self.ipaddress

このようにすると、IPaddressテーブルの中身を表示します。

⑦IPaddressテーブルのフィールド情報も表示させる場合、admin.pyを編集します。

vi pj1/app1/admin.py

変更前

from django.contrib import admin

# Register your models here.

# 追記
from app1.models import Ipaddress

# 追記
admin.site.register(Ipaddress)

変更後

from django.contrib import admin

# Register your models here.

# 追記
from app1.models import Ipaddress

# 以下を追加
class IpaddressAdmin(admin.ModelAdmin):
    list_display = ('ipaddress', 'status', 'description')

# 追記
admin.site.register(Ipaddress, IpaddressAdmin)

このようにすることで管理サイトの表示をカスタマイズしていくことができます。

⑧実際のデータベースで正しくアドレス情報が追加されたかMariaDBを確認します。

mysql -u app1_user -papp1_passwd
MariaDB [(none)]> USE app1_db;
MariaDB [app1_db]> SELECT * FROM app1_ipaddress;
+----+-------------+---------------+-----------------+
| id | ipaddress   | status        | description     |
+----+-------------+---------------+-----------------+
|  1 | 192.168.0.0 | not_available | Network address |
|  2 | 192.168.0.1 | available     |                 |
|  3 | 192.168.0.2 | available     |                 |
+----+-------------+---------------+-----------------+
3 rows in set (0.00 sec)

Djangoは、SQLコマンドを直接叩かずに管理サイトからレコード情報を追加・削除することができます。

次回

次回はDjangoのDBにあるレコード情報を出力します。

VagrantでDjangoで作るWebアプリケーションを作る(その4 レコード情報を出力)

トラックバック用のURL
プロフィール

名前:イワサキ ユウタ 職業:システムエンジニア、ウェブマスター、フロントエンドエンジニア 誕生:1986年生まれ 出身:静岡県 特技:ウッドベース 略歴 20

最近の投稿
人気記事
カテゴリー
広告