Djangoでモデルを作るの前提条件
注意 ※バージョンや環境によっては正常に動作しない可能性があります。
以下で、Pythonの仮想環境を作っています。
以下で、トップページを表示しています。
以上の二つの記事で作ったアプリケーションを前提としています。
モデルとは
Djangoのモデルとは、DjangoからPythonを使ってデータベースを簡単に取り扱えるようにした仕組み、みたいなものです。
「python manage.py startapp 名前」でDjangoのアプリを作ると、自動でmodels.pyというファイルが作られます。
このmodels.pyに、models.Modelを継承したクラスを作り、マイグレーションすることで、データベースに反映することができます。
クラス名がテーブル名、クラスの中に指定する変数が各カラムになります。
SQL文を直接書かなくても、Pythonでデータベースを扱うことができます。
Djangoには標準でSQLiteがついているので、この記事ではSQLiteを使います。
SQLiteは簡易的なデータベースなので、実際に運用する場合はMySQLやPostgreSQLなどを使うことが多いです。
公式チュートリアルでは以下の内容を含みます。
モデルを作る
setting.pyのデータベース設定
setting.pyの中に、以下のようにデータベースの記述があります。
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } }
デフォルトでは、SQLiteが設定されています。
SQLiteを使う場合は、特に何もしなくても使えます。
プロジェクトを作ると、「db.sqlite3」というファイルが自動で作成されているからです。
DATABASESの記述を変えることで、他のデータベースを使うことができます。
以下はPostgreSQLを使う時の例です。
各種パスワードなどは自分で設定します。
直に書き込むのではなく、環境変数として設定することで、セキュリティを高めます。
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'データベースの名前', 'USER': 'データベースのユーザー', 'PASSWORD': 'データベースのパスワード', 'HOST': 'localhost 開発環境ではローカルホスト', 'PORT': '5432 postgreSQLだとこの数字', } }
「django.db.backends.」の後に記載するもので、使うデータベースを変えます。各種設定が違うデータベースもあるかもです。
postgresql_psycopg2というのは、PythonでPostgreSQLを使うためのデータベースアダプタです。
Djangoのsetting.pyで、psycopg2を設定することで、PostgreSQLを使うことができます。
これはデータベースごとに違うものを使います。MySQLならばMySQL用のものがあります。
この記事では、デフォルトのSQLiteを使います。
SQLiteにテーブルを作る
models.pyにモデルを作る
まず、models.pyにクラスを作ります。
models.py には最初からmodelsがimportされています。
このmodels.Modelを継承したクラスを作ります。
以下は間違いがある例です。
from django.db import models class Book(models.Model): isbn = models.CharField('ISBN', max_length=20) title = models.CharField('書名') author = models.CharField('著者') memo = models.TextField('メモ') def __str__(self): return self.title
今回は書籍のデータベースを例として作りました。
クラス名Bookの中に、ISBNコードと書名と著者名のデータベースを作ります。
○○Fieldはデータ型を決めています。
CharFieldは文字列を表します。max_lengthの設定が必須でして、上の例だと以下のエラーがでます。
(.venv) C:\python_venv\test-site>python manage.py makemigrations top SystemCheckError: System check identified some issues: ERRORS: top.Book.author: (fields.E120) CharFields must define a 'max_length' attribute. top.Book.title: (fields.E120) CharFields must define a 'max_length' attribute.
ということで、以下のように治します。
from django.db import models class Book(models.Model): isbn = models.CharField('ISBN', max_length=20) title = models.CharField('書名', max_length=100) author = models.CharField('著者', max_length=50) memo = models.TextField('メモ') def __str__(self): return self.title
def __str__は良く使うやつです。
ここでの役割は、adminの管理画面にて、このデータベースを参照したときに、Bookテーブルを開いた時の各レコードの表示名として使われます。
この__str__は、format()やprint()を使うと呼び出される文字列で出力を返すためのメソッド、というのが簡単な説明になります。
データベースマイグレーション
クラスを作っただけでは、テーブルは作られていません。
マイグレーションという処理をすることで、データベースにテーブルが作られます。
Djangoでは「makemigrations」というコマンドでマイグレーションファイルを作成して、「migrate」というコマンドでモデルをデータベースに反映させるという処理を行います。
「makemigrations」「migrate」を実行すると、models.pyに作った各クラスが、テーブルとして登録されます。
makemigrationsコマンドを実行する
以下、makemigrationsコマンドを実行します。
(.venv) C:\python_venv\test-site>python manage.py makemigrations top Migrations for 'top': top\migrations\0001_initial.py - Create model Book
コマンドとしては「python manage.py makemigrations アプリ名」になります。
これをすると、migrationsフォルダに0001_initial.pyというファイルが作られます。
中身はこんな感じ。
from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='Book', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('isbn', models.CharField(max_length=20, verbose_name='ISBN')), ('title', models.CharField(max_length=100, verbose_name='書名')), ('author', models.CharField(max_length=50, verbose_name='著者')), ('memo', models.TextField(verbose_name='メモ')), ], ), ]
‘ISBN’などとmodels.pyで設定しましたが、それらはverbose_nameとなってデータベースの日本語の見出しになります。
idという変数は作っていませんが、models.pyでプライマリーキーを設定しないと、自動で作られます。勝手に連番で振られるプライマリーキーが嫌な場合は、models.pyで設定しておく必要があります。
migrateコマンドを実行する
次に、migrateコマンドを実行します。
(.venv) C:\python_venv\test-site>python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions, top 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 sessions.0001_initial... OK Applying top.0001_initial... OK
すると、topアプリのテーブルと一緒に、Djangoの機能として、以下のテーブルが自動で生成されます。
auth_group auth_group_permissions auth_permission auth_user auth_user_groups auth_user_user_permissions django_admin_log djanog_content_type django_migrations django_session
authとついているものはパーミッションに関するものです。
Djangoにはデフォルトで管理サイトが用意されています。
作成したデータベースのテーブルに対しての権限を、ユーザーごとに設定したり、なんてことができます。
そういった機能をDjangoは最初から用意してくれているわけですね。
それらの機能のために、マイグレーションをしたときにテーブルを作ります。
setting.pyに最初から記載されているdjango.contrib.authというアプリがその機能のアプリになります。
また、マイグレーションの履歴が保存されるテーブルなど、Djangoの内部で使用するテーブルが作られます。
とりあえずは、そんなのも作られるんだなぐらいで大丈夫ですが、django.contrib.authなどはログイン機能などを作るときに関係してきたりしますので、作られていることは覚えておくと良いと思います。
これでデータベースにBookテーブルのひな形ができました。
次は、このデータベースを管理画面から触ってみましょう。
Django管理サイトでデータベースを触る
admin.pyにテーブルを登録する
Django管理サイトで登録したモデルを使用する場合は、admin.pyに記述が必要になります。
from django.contrib import admin from .models import Book admin.site.register(Book)
admin.site.register(Book)という記述を入れることで、models.pyにつくったBookがDjango管理サイトで使えるようになります。
Django管理サイト用のユーザーを作る
Django管理サイトはユーザーを作ってログインして使うサイトです。
なので、ログインできるユーザーを作る必要があります。
以下のコマンドでユーザーを作ることができます。
(.venv) C:\python_venv\test-site>python manage.py createsuperuser ユーザー名 (leave blank to use 'windowsのユーザー名'): test-test メールアドレス: aa@bb.com Password: Password (again): Superuser created successfully.
createsuperuserとすると、名前、メールアドレス、パスワード、パスワードの再入力を求められ、完了するとユーザーが作成されます。
ユーザー名はブランクにすると、windows環境では、windowsのユーザー名になるようです。他のOSはわからないです。
メールアドレスはとりあえずメールアドレスの形式をしていれば実際にメールが送れなくても通ってしまいます。
パスワードは確認用に二回入力する必要があります。
ユーザーを作ったら、次はサイトにアクセスします。
python manage.py runserver で開発サーバーを起動し、http://localhost:8000/admin/にアクセスします。
すると、ログイン画面がでてきます。
先ほどのcreatesuperuserコマンドで作成したユーザー名とパスワードでログインします。
admin.pyに記述を追加していれば、ユーザーのほかにBookというテーブルができています。
Bookの中に入ると、何もない状態です。空です。
追加を押すと、入力画面がでます。
ここで、登録して保存すると、データベースにデータを追加できます。
大量の初期データを作る場合は、fixturesというフォルダにjsonファイルなどで初期データを作って登録する方法があります。
これで、一応DjangoでPythonで記述することで、簡単にデータベースを制御することができます。
まとめ
とりあえずこの記事ではモデルを作るところまでですが、このモデルを作ってデータを登録しておくことで、SQLを意識せずに、データをテンプレートに渡すことができます。
web用のフレームワークでは、データベースに簡単にアクセスできることが重要です。動的なサイトを簡単に作れるからです。
「DjangoでビューとテンプレートとURLディスパッチャを使ってとりあえずのページを表示する【Django学習記録】」でも触れたように、テンプレートにデータを渡し、それをWebページに表示することができますが、そのデータをデータベースから引っ張ってくることで、動的なサイトを簡単に作れるようになります。
ビューとテンプレートとURLディスパッチャで、ページを表示し、そのページに持ってくるデータをモデルで作っておく、というのが、Djangoの基礎の基礎になります。
また、こつこつ勉強していこうと思います。