Django

Djangoでモデルを作る【Django学習記録】

Djangoでモデルを作るの前提条件

注意 ※バージョンや環境によっては正常に動作しない可能性があります。

以下で、Pythonの仮想環境を作っています。

Djangoのプロジェクトとアプリケーションを仮想環境で作る【Django】
Djangoのプロジェクトを仮想環境で作るの概要 注意 ※バージョンや環境によっては正常に動作しない可能性があります。 Pipenvで作ったPythonの仮想環境にDjangoをインストールし、最低限のプロジェクトを作る記事です。 ...

以下で、トップページを表示しています。

DjangoでビューとテンプレートとURLディスパッチャを使ってとりあえずのページを表示する【Django学習記録】
DjangoでビューとテンプレートとURLディスパッチャを使ってとりあえずのページを表示するの概要 注意 ※バージョンや環境によっては正常に動作しない可能性があります。 Djangoに限らずですが、初心者の方がプログラミングを勉...

以上の二つの記事で作ったアプリケーションを前提としています。

モデルとは

Djangoのモデルとは、DjangoからPythonを使ってデータベースを簡単に取り扱えるようにした仕組み、みたいなものです。

「python manage.py startapp 名前」でDjangoのアプリを作ると、自動でmodels.pyというファイルが作られます。

このmodels.pyに、models.Modelを継承したクラスを作り、マイグレーションすることで、データベースに反映することができます。

クラス名がテーブル名、クラスの中に指定する変数が各カラムになります。

SQL文を直接書かなくても、Pythonでデータベースを扱うことができます。

Djangoには標準でSQLiteがついているので、この記事ではSQLiteを使います。

SQLiteは簡易的なデータベースなので、実際に運用する場合はMySQLやPostgreSQLなどを使うことが多いです。

公式チュートリアルでは以下の内容を含みます。

Django
The web framework for perfectionists with deadlines.

モデルを作る

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を使うためのデータベースアダプタです。

psycopg2
psycopg2 - Python-PostgreSQL Database Adapter

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/にアクセスします。

Django管理サイトログイン画面

すると、ログイン画面がでてきます。

先ほどのcreatesuperuserコマンドで作成したユーザー名とパスワードでログインします。

admin.pyに記述を追加していれば、ユーザーのほかにBookというテーブルができています。

Bookの中に入ると、何もない状態です。空です。

追加を押すと、入力画面がでます。

ここで、登録して保存すると、データベースにデータを追加できます。

大量の初期データを作る場合は、fixturesというフォルダにjsonファイルなどで初期データを作って登録する方法があります。

これで、一応DjangoでPythonで記述することで、簡単にデータベースを制御することができます。

まとめ

とりあえずこの記事ではモデルを作るところまでですが、このモデルを作ってデータを登録しておくことで、SQLを意識せずに、データをテンプレートに渡すことができます。

web用のフレームワークでは、データベースに簡単にアクセスできることが重要です。動的なサイトを簡単に作れるからです。

「DjangoでビューとテンプレートとURLディスパッチャを使ってとりあえずのページを表示する【Django学習記録】」でも触れたように、テンプレートにデータを渡し、それをWebページに表示することができますが、そのデータをデータベースから引っ張ってくることで、動的なサイトを簡単に作れるようになります。

ビューとテンプレートとURLディスパッチャで、ページを表示し、そのページに持ってくるデータをモデルで作っておく、というのが、Djangoの基礎の基礎になります。

また、こつこつ勉強していこうと思います。

タイトルとURLをコピーしました