Djangoモデルを作成する方法

前書き

前のチュートリアルでは、「https://www.digitalocean.com/community/tutorials/how-to-create-a-django-app-and-connect-it-to-a-database[Djangoアプリの作成方法] MySQLデータベースの作成方法、Djangoアプリケーションの作成と起動方法、およびMySQLデータベースへの接続方法について説明しました。

このチュートリアルでは、保存するBlogアプリケーションデータのフィールドと動作を定義するDjango * models *を作成します。 これらのモデルは、Djangoアプリケーションのデータをデータベースにマッピングします。 Djangoは、「モデル」と呼ばれるオブジェクトリレーショナルマッピング(ORM)APIを介してデータベーステーブルを生成するために使用します。

前提条件

MySQLをUbuntu 16.04サーバーにインストールし、Djangoアプリケーションとデータベース接続をセットアップする必要があります。 まだこれを行っていない場合は、Djangoシリーズのパート2、「https://www.digitalocean.com/community/tutorials/how-to-create-a-django-app-and-connect-」を参照してください。 it-to-a-database [Djangoアプリを作成してデータベースに接続する方法]。

ステップ1-Djangoアプリケーションを作成する

モジュール性のDjango哲学を維持するために、ブログWebサイトの作成に必要なすべてのファイルを含むDjangoアプリをプロジェクト内に作成します。

最初にPython仮想環境をアクティブにします。

cd ~/my_blog_app
. env/bin/activate
cd blog

そこから、このコマンドを実行しましょう:

python manage.py startapp blogsite

この時点で、プロジェクトに次のディレクトリ構造が作成されます。

my_blog_app/
└── blog
   ├── blog
   │   ├── __init__.py
   │   ├── __pycache__
   │   │   ├── __init__.cpython-35.pyc
   │   │   ├── settings.cpython-35.pyc
   │   │   ├── urls.cpython-35.pyc
   │   │   └── wsgi.cpython-35.pyc
   │   ├── settings.py
   │   ├── urls.py
   │   └── wsgi.py
   ├── blogsite
   │   ├── admin.py
   │   ├── apps.py
   │   ├── __init__.py
   │   ├── migrations
   │   │   └── __init__.py
   │   ├── models.py
   │   ├── tests.py
   │   └── views.py
   └── manage.py

このチュートリアルで注目するファイルは、 `+ models.py +`ファイルです。

ステップ2-投稿モデルを追加する

まず、 + Posts`モデルを生成するためのコードが含まれるように、 + models.py + `ファイルを開いて編集する必要があります。 `+ Post +`モデルには次のデータベースフィールドが含まれます。

  • + title +-ブログ投稿のタイトル。

  • + slug +-Webページの有効なURLが保存および生成される場所。

  • + content +-ブログ投稿のテキストコンテンツ。

  • + created_on +-投稿が作成された日付。

  • + author of-投稿を書いた人。

ここで、 `+ models.py +`ファイルが含まれているディレクトリに移動します。

cd ~/my_blog_app/blog/blogsite

端末のファイルの内容を表示するには、 `+ cat +`コマンドを使用します。

cat models.py

ファイルには、モデルをインポートする次のコードと、この `+ models.py +`ファイルに配置する内容を説明するコメントが必要です。

models.py

from django.db import models

# Create your models here.

お気に入りのテキストエディターまたはIDEを使用して、次のコードを `+ models.py `ファイルに追加します。 テキストエディタとして「 nano」を使用します。 しかし、あなたが好きなものを使用することは大歓迎です。

nano models.py

このファイル内には、モデルAPIをインポートするコードがすでに追加されています。先に進み、続くコメントを削除できます。 次に、文字列からスラッグを生成するための `+ slugify `と、認証のためのDjangoの ` User +`をインポートします。

models.py

from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User

次に、 + Post +`を呼び出すモデルクラスにクラスメソッドを追加します。次のデータベースフィールドは `+ title ++ slug ++ content +、 `+ created_on `および ` author +`です。

models.py

...
class Post(models.Model):
   title = models.CharField(max_length=255)
   slug = models.SlugField(unique=True, max_length=255)
   content = models.TextField()
   created_on = models.DateTimeField(auto_now_add=True)
   author = models.TextField()

次に、URLを生成する機能と投稿を保存する機能を追加します。 これは、私たちのユニークな投稿に一致するユニークなリンクを作成するため、重要です。

models.py

...
@models.permalink
def get_absolute_url(self):
    return ('blog_post_detail', (),
         {
            'slug': self.slug,
         })
def save(self, *args, **kwargs):
    if not self.slug:
        self.slug = slugify(self.title)
        super(Post, self).save(*args, **kwargs)

次に、投稿がどのように順序付けられ、Webページに表示されるかをモデルに伝える必要があります。 このロジックは、ネストされた内部の `+ Meta `クラスに追加されます。 通常、 ` Meta +`クラスには、データベースフィールドの定義に関連しない他の重要なモデルロジックが含まれます。

models.py

...
  class Meta:
       ordering = ['created_on']
       def __unicode__(self):
           return self.title

最後に、このファイルに `+ Comment `モデルを追加します。 これには、署名に ` models.Models `が含まれる ` Comment +`という名前の別のクラスを追加し、次のデータベースフィールドを定義する必要があります。

  • + name +-コメントを投稿した人の名前。

  • + email +-コメントを投稿した人のメールアドレス。

  • + text +-コメント自体のテキスト。

  • + post-コメントが作成された投稿。

  • + created_on +-コメントが作成された時刻。

models.py

...
class Comment(models.Model):
   name = models.CharField(max_length=42)
   email = models.EmailField(max_length=75)
   website = models.URLField(max_length=200, null=True, blank=True)
   content = models.TextField()
   post = models.ForeignKey(Post, on_delete=models.CASCADE)
   created_on = models.DateTimeField(auto_now_add=True)

終了すると、完全な `+ models.py +`ファイルは次のようになります。

models.py

from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User


class Post(models.Model):
   title = models.CharField(max_length=255)
   slug = models.SlugField(unique=True, max_length=255)
   content = models.TextField()
   created_on = models.DateTimeField(auto_now_add=True)
   author = models.TextField()

   @models.permalink
   def get_absolute_url(self):
       return ('blog_post_detail', (),
               {
                  'slug': self.slug,
               })

   def save(self, *args, **kwargs):
       if not self.slug:
           self.slug = slugify(self.title)
       super(Post, self).save(*args, **kwargs)

   class Meta:
       ordering = ['created_on']

       def __unicode__(self):
           return self.title


class Comment(models.Model):
   name = models.CharField(max_length=42)
   email = models.EmailField(max_length=75)
   website = models.URLField(max_length=200, null=True, blank=True)
   content = models.TextField()
   post = models.ForeignKey(Post, on_delete=models.CASCADE)
   created_on = models.DateTimeField(auto_now_add=True)

必ずファイルを保存して閉じてください。

+ models.py`ファイルをセットアップしたら、 + settings.pyc`ファイルを更新できます。

ステップ3-設定の更新

アプリケーションにモデルを追加したので、追加したばかりの + blogsite +`アプリの存在をプロジェクトに通知する必要があります。 これを行うには、これを `+ settings.py`の + INSTALLED APPS`セクションに追加します。

`+ settings.py +`が存在するディレクトリに移動します。

cd ~/my_blog_app/blog/blog

ここから、たとえばコマンド `+ nano settings.py `を使用して、nanoで ` settings.py +`ファイルを開きます。

ファイルを開いた状態で、以下に示すように、ファイルの `+ INSTALLED_APPS `セクションに ` blogsite +`アプリを追加します。

settings.py

# Application definition
INSTALLED_APPS = [

   'django.contrib.admin',
   'django.contrib.auth',
   'django.contrib.contenttypes',
   'django.contrib.sessions',
   'django.contrib.messages',
   'django.contrib.staticfiles',
]

`+ blogsite +`アプリを追加すると、ファイルを保存して終了できます。

この時点で、これらの変更を適用する準備が整いました。

ステップ4-移行を行う

モデル「+ Post 」と「 Comment 」を追加したら、次のステップはこれらの変更を適用して、「 MySQL +」データベーススキーマがそれらを認識し、必要なテーブルを作成するようにすることです。

`+ blog_data +`データベースに既に存在するテーブルを見てみましょう。

これを行うには、MySQLサーバーにログインする必要があります。

mysql blog_data -u root

「+ SHOW DATABASES; +」コマンドを入力すると、次のように表示されます。

Output+--------------------+
| Database           |
+--------------------+
| information_schema |
| blog_data          |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

`+ blog_data +`データベースを見て、すでに存在するテーブルがあればそれを表示します。

USE blog_data;

次に、 `+ blog_data +`データベースに存在するテーブルをリストします:

SHOW TABLES;
OutputEmpty set (0.00 sec)

現在のところ、まだ移行を行っていないため、テーブルは表示されません。 ただし、移行を行うと、Djangoによって生成されたテーブルが表示されます。

次に、 `+ models.py +`で行った変更を適用する移行を行います。

+ CTRL + + `+ D +`でMySQLを閉じます。

まず、コマンド `+ makemigrations `を使用して、モデルの変更を個々の移行ファイルにパッケージ化する必要があります。 これらのファイルは、 ` git `のようなバージョン管理システムの ` commits +`のファイルに似ています。

さて、 `〜/ my_blog_app / blog / blogsite / migrations +`に移動して ` ls `を実行すると、 ` init 。py +`ファイルしかないことに気付くでしょう。 これは、移行を追加すると変更されます。

次のように、 `+ cd +`を使用してブログディレクトリに移動します。

cd ~/my_blog_app/blog
python manage.py makemigrations

ターミナルウィンドウに次の出力が表示されます。

OutputMigrations for 'blogsite':
 blogsite/migrations/0001_initial.py
   - Create model Comment
   - Create model Post
   - Add field post to comment

`+ /〜/ my_blog_app / blog / blogsite / migrations `に移動したときに、 ` init 。py `ファイルしかなかったことを覚えていますか? そのディレクトリに「 cd 」を戻すと、「 pycache 」と「 0001_initial.py 」の2つのものが追加されていることがわかります。 ` makemigrations `を実行すると、 ` 0001_initial.py `ファイルが自動的に生成されました。 同様のファイルは、 ` makemigrations +`を実行するたびに生成されます。

ファイルの内容を確認するには、「+ less 0001_initial.py +」を実行します。

次に、「+〜/ my blog app / blog」に移動します。

移行ファイルを作成したので、コマンド「+ migrate 」を使用して、これらのファイルが記述する変更をデータベースに適用する必要があります。 しかし最初に、 ` showmigrations +`コマンドを使用して、現在の移行が存在するものを見てみましょう。

python manage.py showmigrations
Outputadmin
[ ] 0001_initial
[ ] 0002_logentry_remove_auto_add
auth
[ ] 0001_initial
[ ] 0002_alter_permission_name_max_length
[ ] 0003_alter_user_email_max_length
[ ] 0004_alter_user_username_opts
[ ] 0005_alter_user_last_login_null
[ ] 0006_require_contenttypes_0002
[ ] 0007_alter_validators_add_error_messages
[ ] 0008_alter_user_username_max_length
[ ] 0009_alter_user_last_name_max_length
blogsite
[ ] 0001_initial
contenttypes
[ ] 0001_initial
[ ] 0002_remove_content_type_name
sessions
[ ] 0001_initial

「+ blogsite 」用に追加した移行には、モデル「 Post 」および「 Comment 」用の移行「 0001_initial +」が含まれています。

次のコマンドを使用して、移行を行った後に実行される `+ SQL`ステートメントを見てみましょう。 移行と移行のタイトルを引数として受け取ります。

python manage.py sqlmigrate blogsite 0001_initial

以下に示すように、これは実際に行われているSQLクエリです。

BEGIN;
--
-- Create model Comment
--
CREATE TABLE `blogsite_comment` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(42) NOT NULL, `email` varchar(75) NOT NULL, `website` varchar(200) NULL, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL);
--
-- Create model Post
--
CREATE TABLE `blogsite_post` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `title` varchar(255) NOT NULL, `slug` varchar(255) NOT NULL UNIQUE, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL, `author` longtext NOT NULL);
--
-- Add field post to comment
--
ALTER TABLE `blogsite_comment` ADD COLUMN `post_id` integer NOT NULL;
ALTER TABLE `blogsite_comment` ADD CONSTRAINT `blogsite_comment_post_id_de248bfe_fk_blogsite_post_id` FOREIGN KEY (`post_id`) REFERENCES `blogsite_post` (`id`);
COMMIT;

次に、MySQLデータベースに適用されるように移行を実行しましょう。

python manage.py migrate

次の出力が表示されます。

OutputOperations to perform:
 Apply all migrations: admin, auth, blogsite, 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 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 blogsite.0001_initial... OK
 Applying sessions.0001_initial... OK

これで移行が正常に適用されました。

Djangoのドキュメントに記載されているように、MySQLをバックエンドとして使用したDjangoの移行には3つの注意事項があることに留意することが重要です。

  • スキーマ変更操作に関するトランザクションのサポートの欠如。 つまり、移行が正常に適用されない場合、別の移行を試行するには、行った変更を手動で選択解除する必要があります。 失敗した移行で変更が行われる前に、以前の時点にロールバックすることはできません。

  • ほとんどのスキーマ変更操作では、MySQLはテーブルを完全に書き換えます。 最悪の場合、時間の複雑さは、列を追加または削除するテーブルの行数に比例します。 Djangoのドキュメントによると、これは100万行につき1分程度の遅い可能性があります。

  • MySQLでは、列、テーブル、インデックスの名前の長さに小さな制限があります。 また、すべての列とインデックスカバーの合計サイズにも制限があります。 他のバックエンドはDjangoで作成されたより高い制限をサポートできますが、MySQLバックエンドが適切に配置されていると同じインデックスを作成できません。

Djangoでの使用を検討している各データベースについて、それぞれの長所と短所を必ず検討してください。

手順5-データベーススキーマの検証

移行が完了したら、Djangoモデルを介して作成したMySQLテーブルが正常に生成されたことを確認する必要があります。

これを行うには、ターミナルで次のコマンドを実行してMySQLにログインします。

mysql blog_data -u root

存在するデータベースを表示します。

SHOW DATABASES;

データベース `+ blog_data +`を選択します。

USE blog_data;

次に、次のコマンドを入力してテーブルを表示します。

SHOW TABLES;

以下が表示されるはずです。

Output+----------------------------+
| Tables_in_blog_data        |
+----------------------------+
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| blogsite_comment           |
| blogsite_post              |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+

「+ blogsite_comment 」と「 blogsite_post +」が表示されます。 これらは私たちが自分たちで作ったモデルです。 定義したフィールドが含まれていることを検証しましょう。

DESCRIBE blogsite_comment;
Output+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| name       | varchar(42)  | NO   |     | NULL    |                |
| email      | varchar(75)  | NO   |     | NULL    |                |
| website    | varchar(200) | YES  |     | NULL    |                |
| content    | longtext     | NO   |     | NULL    |                |
| created_on | datetime(6)  | NO   |     | NULL    |                |
| post_id    | int(11)      | NO   | MUL | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
7 rows in set (0.01 sec)
DESCRIBE blogsite_post;
Output+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| title      | varchar(255) | NO   |     | NULL    |                |
| slug       | varchar(255) | NO   | UNI | NULL    |                |
| content    | longtext     | NO   |     | NULL    |                |
| created_on | datetime(6)  | NO   |     | NULL    |                |
| author     | longtext     | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)

Djangoモデルの移行からデータベーステーブルが正常に生成されたことを確認しました。

+ CTRL + + `+ D `でMySQLを閉じることができ、Python環境から離れる準備ができたら、 ` deactivate +`コマンドを実行できます。

deactivate

プログラミング環境を非アクティブ化すると、ターミナルコマンドプロンプトに戻ります。

結論

このチュートリアルでは、ブログWebアプリケーションの基本機能のモデルを正常に追加しました。 「+ models 」のコーディング方法、「 migrations 」の仕組み、およびDjangoの「 models 」を実際の「 MySQL +」データベーステーブルに変換するプロセスを学習しました。

Related