如何在 Django 之外使用 Django 模型?

Posted

技术标签:

【中文标题】如何在 Django 之外使用 Django 模型?【英文标题】:How to use Django models outside of Django? 【发布时间】:2019-08-10 09:16:26 【问题描述】:

按照this 指南,我可以通过调用python main.py 来使用具有以下文件结构的Django 之外的模型。

├── data
│   ├── __init__.py
│   ├── migrations
│   │   └── __init__.py
│   └── models.py
├── main.py
├── manage.py
└── settings.py

main.py 看起来像这样:

import os, django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')

django.setup()
from data.models import Foo, Bar #...

print(Foo.objects.all()) #this works fine

我想做的是把它变成一个名为db的“包”,看起来像这样:

    ├── data
    │   ├── __init__.py
    │   ├── migrations
    │   │   └── __init__.py
    │   └── models.py
    ├── __init__.py 
    ├── manage.py
    └── settings.py

db 包的__init__.py 中,我想这样做:

import os, django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')

django.setup()
from data.models import Foo, Bar # ...
from django.db import connection

__all__ = [
    'connection',
    'Foo',
    'Bar', 
    #...
]

所以我可以像这样从test.py(与db在同一目录中)调用db包:

import db

print(db.Foo.objects.all()) #this throws an error "no module named data"

或者像这样:

from db import Foo

print(Foo.objects.all()) # this throws an error "no module named settings"

有没有一种方法可以使用 Django 的模型而无需调用: os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings') django.setup()

在每个使用模型的页面上?

我在这里错过了什么?

【问题讨论】:

【参考方案1】:

如果您查看Django apps are loaded 是如何运行的,我认为您需要在应用程序的models.pymodels/init.py 而不是db/__init__.py 中运行您的设置

当 Django 启动时,django.setup() 负责填充 应用程序注册表。

setup(set_prefix=True) 通过以下方式配置 Django:

加载设置。设置日志记录。如果 set_prefix 为 True, 将 URL 解析器脚本前缀设置为 FORCE_SCRIPT_NAME 如果 定义,或/否则。初始化应用程序注册表。这 函数被自动调用:

通过 Django 的 WSGI 支持运行 HTTP 服务器时。当调用一个 管理命令。在其他情况下必须显式调用它,因为 以纯 Python 脚本编写实例。

应用程序注册表的初始化分为三个阶段。在每一个 阶段,Django按顺序处理所有应用程序 INSTALLED_APPS。

首先 Django 导入 INSTALLED_APPS 中的每个项目。

如果是应用配置类,Django 会导入根目录 应用程序的包,由其名称属性定义。如果它是一个 Python 包,Django 创建一个默认的应用程序配置。

在这个阶段,您的代码不应导入任何模型!

换句话说,您的应用程序的根包和模块 定义你的应用程序配置类不应该导入任何 模型,甚至是间接的。

严格来说,Django 允许导入模型一次 应用程序配置已加载。 但是,为了避免 对 INSTALLED_APPS 的顺序进行不必要的限制,它是强 建议在这个阶段不要导入任何模型。

此阶段完成后,在应用程序上运行的 API get_app_config() 等配置变得可用。

然后 Django 尝试导入每个模型的子模块 应用程序,如果有的话。

您必须在应用程序的 models.py 中定义或导入所有模型 或模型/__init__.py。否则,应用程序注册表可能不会 此时已完全填充,这可能导致 ORM 故障。

此阶段完成后,在模型上运行的 API,例如 get_model() 变得可用。

最后 Django 运行每个应用程序的 ready() 方法 配置。

【讨论】:

以上是关于如何在 Django 之外使用 Django 模型?的主要内容,如果未能解决你的问题,请参考以下文章

为我的应用程序之外的单个模型覆盖 django 管理员更改表单?

Django 中的动态模型字段

Django:如何在查看请求之外获取已登录的用户?

django 抽象模型与常规继承

“max_length”如何影响 Django 模型?

MTV模型(Django)响应模式的简单示例