[Python]Djangoのmodelを実装してみた
1.前回の記事
前回はWebフレームワークのDjangoでWebサーバを立ち上げて、
Webブラウザで立ち上げたサーバにアクセスしてみました。
こんなイメージの環境を作りました。
2.今回おこなう事
Djangoのデータベーステーブルを担当しているmodelについて実装を通じて
学習し、admin管理画面からデータベーステーブルを確認していきたいと
思います。
3.参考書籍
前回から引き続き、次の書籍を参考にしています。
本当にわかりやすく助かっています。
このブログ記事では、書籍のP86以降をやっていきます。
4.環境セットアップ
まず、rootユーザでCentOS7仮想サーバにssh接続し、
/root/djangoディレクトリ配下にblogprojectというプロジェクトを
作成します。
[root@localhost ~]# cd django/
[root@localhost django]# pwd
/root/django
[root@localhost django]# django-admin startproject blogproject
[root@localhost django]# ls
blogproject helloworldproject
次に、blogproject配下にblogpostというアプリを作成します。
アプリの作成方法はmanage.pyにstartappというオプションを付けることで
可能です。
※もしこのコマンドを実行した際にSQLIiteのバージョンが古いという
出力がされて実行出来なかった場合は、前回の記事と同様に
LD_LIBRARY_PATHをexportしてみてください。
[root@localhost blogproject]# python3 manage.py startapp blogpost
[root@localhost blogproject]# ls
blogpost blogproject manage.py
またプロジェクトとアプリの違いについては、説明すると長くなるので、
今回は割愛します。
参考にしている書籍から図を拝借すると以下のようなイメージです。
もしDjangoをこれから学習したいと思っている方は、何度も言いますが
買ってください。本当にわかりやすい書籍です。
話が少し逸れたので元に戻します。
プロジェクト側のurls.pyを次の様に編集します。
(私の環境では/root/blogproject/blogproject/urls.py)
[root@localhost blogproject]# cat urls.py
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blogpost.urls')),
]
そしてurls.pyと同じディレクトリに存在するsettings.pyについて
★の部分を追加しました。
import os★
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blogpost.apps.BlogpostConfig', ★
]
ALLOWED_HOSTS = ['*']★
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',
],
},
},
]
次にblogpostディレクトリ(=アプリ)にurls.pyファイルを作成。
中身を以下の様にしました。
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
この状態で一度Webサーバを稼働させてみてアクセス出来るか確認します。
[root@localhost blogproject]# pwd
/root/django/blogproject
[root@localhost blogproject]# ls
blogpost blogproject db.sqlite3 manage.py
[root@localhost blogproject]# python manage.py runserver 192.168.184.138:8000
Watching for file changes with StatReloader
Performing system checks...
System check identified some issues:
WARNINGS:
?: (urls.W002) Your URL pattern '/admin' has a route beginning with a '/'. Remove this slash as it is unnecessary. If this pattern is targeted in an include(), ensure the include() pattern has a trailing '/'.
?: (urls.W005) URL namespace 'admin' isn't unique. You may not be able to reverse all URLs in this namespace
System check identified 2 issues (0 silenced).
You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
May 21, 2021 - 00:27:43
Django version 3.2.3, using settings 'blogproject.settings'
Starting development server at http://192.168.184.138:8000/
Quit the server with CONTROL-C.
ホストOSのWebブラウザを使用してWebサーバにアクセスします。
今回はディレクトリを指定し、アクセスしていないので
「そのようなURLを持つページは無いよ!」
と怒られてしまっていますが、アクセス自体は問題無さそうですね!
ここまで来て、ようやく今回のテーマであるmodelを
実装していきたいと思います。
modelとはデータベーステーブルだと思ってくれれば良いみたいです。
これについては後程図式化してみます。
modelのコンフィグはsettings.pyに以下の様に記載されています。
ENGINEのところでWebサーバの裏側で使用するデータベースの種類を
変更することが出来るようです。
今回は初めてのmodel学習の為にSQLiteのまま行きたいと思いますが、
今後はPostgreSQLを使っていきたいなと思います。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
今度はblogpostディレクトリ(=アプリ)配下に存在するmodels.pyを
編集していきます。
このファイルでは、Djangoで使用するデータベーステーブルを定義します。
今回は書籍の通り、以下の様に設定を入れました。
classの後の文字列がデータベーステーブル名となり、それ以降は
データベーステーブル内のアトリビュート(どんなデータを格納するか)
ということになります。
from django.db import models
class SampleModel(models.Model):
title = models.CharField(max_length=100)
number =models.IntegerField()
上記をPostgreSQLで解釈してみると、たぶん以下のような感じだと
思います。
★1
createdb ●●(ここは上記のPythonコードでは記載されていない為)
psql ●●
CREATE TABLE SampleModel(
title varchar(100)
number int
);
models.pyの設定をSQLiteに反映させていくためには
manage.pyの引数にmakemigrationsとmigrateオプションを指定して
順番に実行する必要があるようです。
makemigrationsとmigrateの違いは、
makemigrationsはmodels.pyのコードを元に設計図を作成
migrateは設計図を元にデータベーステーブルを構築
。。。という事なのですが、ちょっとわかりにくいなと感じたのでPostgreSQLと比較した図を作成してみました。
settings.pyにコードを入れこんでデータベーステーブルの定義を行うのは、
PostgreSQLの★1を準備している段階、makemigrationsとmigrateを実行するのは、PostgreSQLの★1を実際に実行してデータベーステーブル
(かつデータベース)を作成するようなイメージなのかなと。
実際にやってみます。
makemigrationsで設計図を作成します。
manage.pyにmakemigrationsオプションを指定します。
[root@localhost blogproject]# pwd
/root/django/blogproject
[root@localhost blogproject]# python manage.py makemigrations
System check identified some issues:
WARNINGS:
?: (urls.W005) URL namespace 'admin' isn't unique. You may not be able to reverse all URLs in this namespace
Migrations for 'blogpost':
blogpost/migrations/0001_initial.py
- Create model SampleModel
次にmigrateを実行して設計図からデータベーステーブルを作ります。
manage.pyにmigrateオプションを指定します。
[root@localhost blogproject]# python manage.py migrate
System check identified some issues:
WARNINGS:
?: (urls.W005) URL namespace 'admin' isn't unique. You may not be able to reverse all URLs in this namespace
Operations to perform:
Apply all migrations: admin, auth, blogpost, contenttypes, 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 admin.0003_logentry_add_action_flag_choices... 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 auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying blogpost.0001_initial... OK
Applying sessions.0001_initial... OK
このデータベーステーブルをDjangoの管理画面で確認していきます。
しかし、このままadmin管理画面にアクセスしても作成した
データベーステーブルを確認することは出来ませんので、
確認出来るようにするための設定を行っていきます。
blogpostディレクトリに存在するadmin.pyを以下の様に編集します。
[root@localhost blogpost]# cat admin.py
from django.contrib import admin
from .models import SampleModel
# Register your models here.
admin.site.register(SampleModel)
その後admin管理画面にアクセスするためのユーザを作成します。
スーパユーザになるわけですが、作成する為には
manage.pyにcreatesuperuserオプションを指定します。SQLみたいです笑
今回はユーザ:test、パスワード:passwordとしました。
[root@localhost blogproject]# python manage.py createsuperuser
System check identified some issues:
WARNINGS:
?: (urls.W005) URL namespace 'admin' isn't unique. You may not be able to reverse all URLs in this namespace
Username (leave blank to use 'root'): test
Email address:
Password:
Password (again):
This password is too common.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
これでCLIでの設定は完了です。
Webサーバを稼働していない場合、稼働します。
[root@localhost blogproject]# python manage.py runserver 192.168.184.138:8000
Watching for file changes with StatReloader
Performing system checks...
System check identified some issues:
WARNINGS:
?: (urls.W005) URL namespace 'admin' isn't unique. You may not be able to reverse all URLs in this namespace
System check identified 1 issue (0 silenced).
May 21, 2021 - 04:21:43
Django version 3.2.3, using settings 'blogproject.settings'
Starting development server at http://192.168.184.138:8000/
Quit the server with CONTROL-C.
稼働したらWebブラウザを開き、runserverで指定したIPアドレスとポートで
アクセスしていきます。
今回のURLは「http://192.168.184.138:8000/admin」となります。
Webブラウザでadmin管理画面にアクセスした画面は以下となります。
createsuperuserで指定したユーザ名とパスワードを入力します。
ログインした画面は以下です。
SampleModelデータベーステーブルがあることが分かります。
テーブル内にデータはありませんが、ADD SAMPLE MODELでデータを追加
することが出来るようです。
models.pyで指定したアトリビュートの項目を入力出来ますね!
実際に適当にデータを入れたスクショが以下になります。
最後に、ここまでのblogprojectプロジェクトのディレクトリ構造は
以下となりました。
[root@localhost django]# tree --charset=C blogproject/
blogproject/
|-- blogpost
| |-- __init__.py
| |-- __pycache__
| | |-- __init__.cpython-36.pyc
| | |-- admin.cpython-36.pyc
| | |-- apps.cpython-36.pyc
| | |-- models.cpython-36.pyc
| | `-- urls.cpython-36.pyc
| |-- admin.py
| |-- apps.py
| |-- migrations
| | |-- 0001_initial.py
| | |-- __init__.py
| | `-- __pycache__
| | |-- 0001_initial.cpython-36.pyc
| | `-- __init__.cpython-36.pyc
| |-- models.py
| |-- tests.py
| |-- urls.py
| `-- views.py
|-- blogproject
| |-- __init__.py
| |-- __pycache__
| | |-- __init__.cpython-36.pyc
| | |-- settings.cpython-36.pyc
| | |-- urls.cpython-36.pyc
| | `-- wsgi.cpython-36.pyc
| |-- asgi.py
| |-- settings.py
| |-- urls.py
| |-- urls.py.old
| `-- wsgi.py
|-- db.sqlite3
`-- manage.py
この記事が参加している募集
この記事が気に入ったらサポートをしてみませんか?