Django モデル

Django は、PostgreSQL、MySQL、SQLite、Oracle など、さまざまなデータベースを優れた形でサポートしています。

Django はこれらのデータベースに対して統一された呼び出し API を提供しています。 自分のビジネスニーズに応じて異なるデータベースを選択できます。

MySQL は Web アプリケーションで最もよく使われるデータベースです。この章では MySQL を例として紹介します。当サイトのMySQL チュートリアルMySQL の基礎知識をさらに学ぶことができます。

mysql ドライバをインストールしていない場合は、次のコマンドを実行してインストールできます:

sudo pip3 install pymysql

Django ORM

Django のモデルは内蔵の ORM を使用します。

オブジェクト関係マッピング(Object Relational Mapping、略称 ORM)は、オブジェクト指向プログラミング言語における異なる型システム間のデータ変換を実現するために使用されます。

ORM はビジネスロジック層とデータベース層の間で橋渡しの役割を果たします。

ORM は、オブジェクトとデータベース間のマッピングを記述するメタデータを使用して、プログラム内のオブジェクトを自動的にデータベースに永続化します。

ORM を使用する利点:

  • 開発効率が向上します。
  • 異なるデータベースへスムーズに切り替えられます。

ORM を使用する欠点:

  • ORM コードを SQL 文に変換する際に一定の時間がかかるため、実行効率が低下することがあります。
  • 長期間 ORM コードを書いていると、SQL 文を作成する能力が低下します。

ORM の解析プロセス:

  • 1. ORM は Python コードを SQL 文に変換します。
  • 2. SQL 文は pymysql を介してデータベースサーバーに送信されます。
  • 3. データベースで SQL 文を実行し、結果を返します。

ORM の対応関係表:


データベース設定

Django で mysql データベースを使用する方法

MySQL データベースの作成(ORM はデータベースレベルでは操作できず、データテーブルレベルでのみ操作できます)構文:

create database 数据库名称 default charset=utf8; # 防止编码问题,指定为 utf8

例えば、サンプル という名前のデータベースを作成し、エンコーディングを utf8 に指定します:

create database サンプル default charset=utf8;   

プロジェクトの settings.py ファイルで DATABASES 設定項目を見つけ、その情報を次のように変更します:

HelloWorld/HelloWorld/settings.py: ファイルコード:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # データベースエンジン 'NAME': 'サンプル', # データベース名 'HOST': '127.0.0.1', # データベースアドレス、ローカル IP アドレス 127.0.0.1 'PORT': 3306, # ポート 'USER': 'root', # データベースユーザー名 'PASSWORD': '123456', # データベースパスワード } }

Python2.x を使用している場合は、ここに中国語のコメントが追加されています。そのため、HelloWorld/settings.py ファイルの先頭に次を追加する必要があります。# -*- coding: UTF-8 -*-。

上記にはデータベース名とユーザーの情報が含まれており、これらは MySQL の対応するデータベースとユーザーの設定と同じです。Django はこの設定に基づいて、MySQL 内の該当するデータベースとユーザーに接続します。

次に、Django に pymysql モジュールを使用して mysql データベースに接続するよう指示します:

インスタンス

# settings.py と同じディレクトリにある __init__.py にモジュールをインポートして設定を行います
import pymysql
pymysql.install_as_MySQLdb()

モデルの定義

APP を作成

Django では、モデルを使用するには app を作成する必要があります。次のコマンドで TestModel という app を作成します:

django-admin startapp TestModel

ディレクトリ構造は次のとおりです:

HelloWorld
|-- HelloWorld
|-- manage.py
...
|-- TestModel
|   |-- __init__.py
|   |-- admin.py
|   |-- models.py
|   |-- tests.py
|   `-- views.py

TestModel/models.py ファイルを次のように変更します:

HelloWorld/TestModel/models.py: ファイルコード:

# models.py from django.db import models class Test(models.Model): name = models.CharField(max_length=20)

上記のクラス名はデータベースのテーブル名を表し、models.Model を継承しています。クラス内のフィールドはデータテーブル内のフィールド(name)を表し、データ型は CharField(varchar に相当)、DateField(datetime に相当)で、max_length パラメータは長さを制限します。

次に settings.py で INSTALLED_APPS 項目を次のように見つけます:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'TestModel',               # 添加此项
)

コマンドラインで実行します:

$ python3 manage.py migrate   # 创建表结构

$ python3 manage.py makemigrations TestModel  # 让 Django 知道我们在我们的模型有一些变更
$ python3 manage.py migrate TestModel   # 创建表结构

"Creating table…" という文字が数行表示されれば、データテーブルの作成は完了です。

Creating tables ...
……
Creating table TestModel_test  #我们自定义的表
……

テーブル名の構成は、アプリケーション名_クラス名(例:TestModel_test)です。

注意:models でテーブルに主キーを設定していなくても、Django は自動的に id を主キーとして追加します。

よくあるエラーメッセージ

上記のコマンドを実行すると、次のようなエラーメッセージが表示される場合があります:

原因は、MySQLclient が現在 Python3.4 までしかサポートしていないため、より高いバージョンの Python を使用している場合は、次のように修正する必要があります:

エラーメッセージのファイルパスから ...site-packages\Django-2.0-py3.6.egg\django\db\backends\mysql パスの base.py ファイルを見つけ、この 2 行のコードをコメントアウトします(コードはファイルの先頭部分にあります):

if version < (1, 3, 13):
    raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__)

通常、エラーのコードファイルパス情報をクリックすると、エラーファイルの該当行に自動的にジャンプします。その時、エラーが発生しているコード行をコメントアウトします。

次のようなエラーメッセージが表示される場合:

エラーのコードファイルパスをクリックして、エラーファイルの該当行にジャンプし、エラーが発生しているコード行の前に次を追加します:

query = query.encode()


データベース操作

次に、HelloWorld ディレクトリに testdb.py ファイルを追加し(後述)、urls.py を変更します:

HelloWorld/HelloWorld/urls.py: ファイルコード:

from django.urls import path from . import views,testdb urlpatterns = [ path('サンプル/', views.サンプル), path('testdb/', testdb.testdb), ]

データの追加

データを追加するには、まずオブジェクトを作成し、次に save 関数を実行する必要があります。これは SQL の INSERT に相当します:

HelloWorld/HelloWorld/testdb.py: ファイルコード:

# -*- coding: utf-8 -*- from django.http import HttpResponse from TestModel.models import Test # データベース操作 def testdb(request): test1 = Test(name='サンプル') test1.save() return HttpResponse("<p>データ追加成功!</p>")

アクセスhttp://127.0.0.1:8000/testdbデータ追加成功のメッセージが表示されます。

出力結果は次のとおりです:

データの取得

Django はデータベースの内容を取得するための複数の方法を提供しています。次のコードのとおりです:

HelloWorld/HelloWorld/testdb.py: ファイルコード:

# -*- coding: utf-8 -*- from django.http import HttpResponse from TestModel.models import Test # データベース操作 def testdb(request): # 初期化 response = "" response1 = "" # objects というモデルマネージャーの all() を使用してすべてのデータ行を取得します。SQL の SELECT * FROM に相当します。 listTest = Test.objects.all() # filter は SQL の WHERE に相当し、条件を設定して結果をフィルタリングできます。 response2 = Test.objects.filter(id=1) # 単一のオブジェクトを取得 response3 = Test.objects.get(id=1) # 返されるデータを制限します。SQL の OFFSET 0 LIMIT 2; に相当します。 Test.objects.order_by('name')[0:2] # データの並び替え Test.objects.order_by("id") # 上記のメソッドはチェーンで使用できます Test.objects.filter(name="サンプル").order_by("id") # すべてのデータを出力 for var in listTest: response1 += var.name + " " response = response1 return HttpResponse("<p>" + response + "</p>")

データの更新

データの変更には save() または update() を使用できます:

HelloWorld/HelloWorld/testdb.py: ファイルコード:

# -*- coding: utf-8 -*- from django.http import HttpResponse from TestModel.models import Test # データベース操作 def testdb(request): # id=1 の name フィールドを変更してから save します。SQL の UPDATE に相当します。 test1 = Test.objects.get(id=1) test1.name = 'Google' test1.save() # もう一つの方法 #Test.objects.filter(id=1).update(name='Google') # すべての列を変更 # Test.objects.all().update(name='Google') return HttpResponse("<p>変更成功</p>")

データの削除

データベース内のオブジェクトを削除するには、そのオブジェクトのdelete()メソッドを呼び出すだけです:

HelloWorld/HelloWorld/testdb.py: ファイルコード:

# -*- coding: utf-8 -*- from django.http import HttpResponse from TestModel.models import Test # データベース操作 def testdb(request): # id=1のデータを削除 test1 = Test.objects.get(id=1) test1.delete() # 別の方法 # Test.objects.filter(id=1).delete() # すべてのデータを削除 # Test.objects.all().delete() return HttpResponse("<p>削除成功</p>")
その他の拡張