DjangoのModelsのみ使用する
はじめに
既存のPythonスクリプトにDB処理を追加する際にDjangoのModelsのみ使用したくなることがありました。DjangoのチュートリアルのDBを例にして、既存のPythonスクリプトにDjangoのModelsを使用するコードを追加する方法を紹介します。
新規のスクリプトでDB処理にDjangoのModelsを使用したい場合は、Djangoのカスタムコマンドを作成したほうがいいと思います。
前提
環境
項目 | 内容 |
---|---|
OS | Windows 10 Pro |
Python バージョン | 3.7.0 (64bit) |
Django バージョン | 2.1.3 |
作成済みのDB(DjangoのチュートリアルのDB)
作成済みのDBとして、チュートリアルのその2まで行ったSQLiteのファイル(db.sqlite3
)を使用します。
Django関連のPythonスクリプト
Django関連のPythonスクリプトの配置
DjangoのModelsを使用するためのスクリプト(app.py
とmodels.py
)を、既存のプロジェクトディレクトリ直下に pollsディレクトリを作成しその下に配置します。
既存のプロジェクトディレクトリ
├─ main.py
├─ db
│ └── db.sqlite3
└─ polls
├── apps.py
└── models.py
app.py の内容
チュートリアルのその1で作成されるapp.py
と同じ内容で作成します。
from django.apps import AppConfig
class PollsConfig(AppConfig):
name = 'polls'
models.py の内容
チュートリアルのその2で作成するmodels.py
と以下の点が異なります。
- 作成済みのDBを使用するために、
class Meta
にdb_table
プロパティとmanged
プロパティを指定する。 db_table
プロパティには、使用するテーブル名を指定する。この例ではSQLiteなのでテーブル名だけですが、別のDB(PostgreSQL等)の場合は必要に応じてスキーマ名等も含めて指定する。manged
プロパティには、マイグレーションを行わないのでFalse
を指定する。
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
class Meta:
db_table = 'polls_question'
managed = False
class Choice(models.Model):
db_table = 'polls_choice'
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
class Meta:
db_table = 'polls_choice'
managed = False
実際は、既存のDBのテーブル定義に合わせてフィールドを作成する必要があります。(inspectdbを使用する方法もあります。)
既存のPythonスクリプトに追加する
既存のPythonスクリプト(main.py
)にModelsを使用するためのコードを追加します。
既存のプロジェクトディレクトリ
├─ main.py
├─ db
│ └── db.sqlite3
└─ polls
├── apps.py
└── models.py
Djangoのセットアップ
main.py
にDjangoをセットアップするコードを追加します。
from django.conf import settings
settings.configure(
DATABASES={
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': './db/db.sqlite3',
}
},
INSTALLED_APPS=['polls.apps.PollsConfig']
)
import django
django.setup()
settings
のconfigure
関数を使用して最低限 必要なDATABASES
とINSTALLED_APPS
を設定する。DATABASES
には、DBの接続情報をdefault
に記載する。記載内容はDBによって異なり、SQLiteの場合はNAME
にSQLiteのファイルパスを指定する。INSTALLED_APPS
には、apps.py
に定義したPollsConfig
を指定する。django.setup()
を使用してdjangoをセットアップする。
Modelsを使用する
セットアップまでできたら、DjangoのModelsの使い方は一緒なので以下のようにします。
from django.conf import settings
settings.configure(
DATABASES={
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': './db/db.sqlite3',
}
},
INSTALLED_APPS=['polls.apps.PollsConfig']
)
import django
django.setup()
from polls.models import Question, Choice
for q in Question.objects.all():
print(q.question_text)
for c in Choice.objects.all():
print(c.choice_text)
from polls.models import Question, Choice
をdjango.setup()
より前に書くと以下のエラーが発生します。
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.