在Django中,确认ORM行为的方法是使用一个文件
如何在Django中使用单个文件来验证ORM的行为?
以前我写了一个关于如何在一个文件中创建 hello world 的方法。在 django 中,我可能最想尝试的是 ORM 部分。这是关于如何在仅有一个文件中尝试 ORM 部分的方法。
在最新的Django中,虽然需要稍微修改一下文件才能尝试,但现在已经可以相对容易地做到这一点。
需要完成以下具体工作。
-
- settingsをpython側から設定する
-
- djangoのApplicationRegistryにmodelを登録する
- 各modelのテーブルを生成する
使用Python从设置中进行配置。
如果没有设置“settings”的设置,将会出现以下类似的异常。
django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
按照错误消息所说,要么将DJANGO_SETTINGS_MODULE注册为环境变量,要么调用settings.configure()。
以下是最基本必需的设置。
from django.conf import settings
settings.configure(
DEBUG=True,
DATABASES={"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": ":memory:"
}},
INSTALLED_APPS=[__name__]
)
在输出SQL查询结果时,将DEBUG=True设置为True是很有必要的,因此最好添加上它。另外,DB的设置也是必需的。在这里,我们指定了一个内存中的SQLite数据库。关于INSTALLED_APPS,如果在注册模型时忘记指定,那么ManyToMany关系可能无法正常工作。
在Django的ApplicationRegistry中注册模型。
请调用django.setup()函数。这将触发django.apps.registry.Apps的populate()函数。在populate()函数内部,将会注册model到django的注册表中。如果忽略了这一步骤,那么在调用Model.save()的时候可能会导致以下错误的发生。
django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.
作为另一个注意事项,请在定义模型时设置app_label。如果没有设置,将无法生成模型类。会出现以下类似的错误。
IndexError: list index out of range
这是在定义时应该采取的步骤。
class X(models.Model):
name = models.CharField(max_length=255, default="foo", blank=True)
class Meta:
app_label = __name__
生成不同model的表格
在通常情况下,我们会使用类似于 “python manage.py migrate” 的命令来生成数据库表格。但是,在只有一个文件的情况下,没有这个步骤。我们需要考虑其他方法。
比如,可以创建一个函数来生成表格。
from django.db import connections
from django.core.management.color import no_style
def create_table(model):
connection = connections['default']
cursor = connection.cursor()
sql, references = connection.creation.sql_create_model(model, no_style())
for statement in sql:
cursor.execute(statement)
for f in model._meta.many_to_many:
create_table(f.rel.through)
# 一つ一つ生成していく必要がある
create_table(X)
总结
总结以上内容如下,这样您就可以方便地确认模型的行为了。
# -*- coding:utf-8 -*-
import django
from django.db import models
from django.conf import settings
from django.db import connections
from django.core.management.color import no_style
settings.configure(
DEBUG=True,
DATABASES={"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": ":memory:"
}},
INSTALLED_APPS=[__name__]
)
def create_table(model):
connection = connections['default']
cursor = connection.cursor()
sql, references = connection.creation.sql_create_model(model, no_style())
for statement in sql:
cursor.execute(statement)
for f in model._meta.many_to_many:
create_table(f.rel.through)
class X(models.Model):
name = models.CharField(max_length=255, default="foo", blank=True)
class Meta:
app_label = __name__
if __name__ == "__main__":
import logging
logging.basicConfig(level=logging.DEBUG)
django.setup()
create_table(X)
xs = X.objects.bulk_create([X(id=1), X(id=2), X(id=3)])
print(X.objects.count())