用于 Django 应用程序的 Python 脚本,无需使用 manage.py shell 即可访问模型

Posted

技术标签:

【中文标题】用于 Django 应用程序的 Python 脚本,无需使用 manage.py shell 即可访问模型【英文标题】:Python script for Django app to access models without using manage.py shell 【发布时间】:2011-12-24 05:39:08 【问题描述】:

我正在编写一个脚本来将一些模型对象导入到我的 django 应用程序使用的数据库中。过去我通过运行./manage.py shell 然后import myscript 解决了这个问题。我确信有更好的方法。我希望能够使用python scriptname.py 从我的 HD 上的任何位置调用脚本,并且在该脚本的前几行中,它将执行任何必要的导入/其他操作,以便它可以访问模型对象并表现得好像它是使用manage.py shell 运行的。

我需要在我的脚本中添加什么来实现这一点?

编辑:

基于@Melug 的回答,添加了动态设置 Python 路径以解决问题的“我的 HD 上的任何位置”部分:

import sys
sys.path.append('c:\\my_projec_src_folder')
from myproject import settings
from django.core.management import setup_environ
setup_environ(settings)

【问题讨论】:

这个问题的答案是脚枪。大多数人会想要使用manage.py,因为这个问题广泛用于搜索,而且您不需要调用shell 来使用manage.py。大多数来这里的人都会想要这个答案:***.com/a/8047520/108512 【参考方案1】:

你需要先设置django环境:

from your_project import settings
from django.core.management import setup_environ
setup_environ(settings)

最后导入你的模型,一切都和 django 一样。

【讨论】:

setup_environ(settings) 自 Django 1.4 起已弃用!我在下面的帖子显示了一个替代方案,包括一个示例。【参考方案2】:

我认为最好的方法是创建您的custom management command(s)。然后你可以在任何地方拨打manage.py <yourcommand>

【讨论】:

从长远来看是更好的选择。 我同意,这是要走的路。这并不比创建一个独立的脚本难多少,而且更加健壮。 虽然是这样,但有时仍需要使用来自其他脚本的 django 模型。【参考方案3】:

从 Django 1.4 开始,您应该避免使用 setup_environ(settings)(Melug 发布),因为它已被弃用。请改用以下内容,您将能够访问您的模型

import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_project_name.settings")

# your imports, e.g. Django models
from your_project_name.models import Location

# From now onwards start your script..

以下是访问和修改模型的示例:

if __name__ == '__main__':    
    # e.g. add a new location
    l = Location()
    l.name = 'Berlin'
    l.save()

    # this is an example to access your model
    locations = Location.objects.all()
    print locations

    # e.g. delete the location
    berlin = Location.objects.filter(name='Berlin')
    print berlin
    berlin.delete()

示例模型:

class Location(models.Model):
    name = models.CharField(max_length=100)

【讨论】:

只有在导入 os.否则,这是一个更好的解决方案。 好点,彼得!也许某些模型导入仅在 os.environ.setdefault(...) 行之后起作用。我在我的帖子中重新安排了导入,现在它应该适用于每个人。 PS:如果你更喜欢这个解决方案,请投票。谢谢! 我可以在没有外部设置文件的情况下执行此操作吗?也就是说,我想在单个脚本中构建模型、连接和所有内容。我不在乎视图... @isaaclw 我不相信没有设置文件你可以做到这一点。如果您找到方法,请告诉我们。顺便提一句。我的settings.py 确实 处理任何视图,它处理连接参数、调试模式等标志等。所有视图都在myapp/views.py 中定义,并且可以通过urls.py 中定义的url 模式访问 我几乎拥有它,我只需要将设置文件设置为某些东西。目前我将其设置为空字符串。 DATABASES = 设置得当。然后:os.environ["DJANGO_SETTINGS_MODULE"] = ''settings.configure(**locals()) 这一切都在 from django.db import models 之前【参考方案4】:

为了也加载模型,我必须将它与 this answer 结合使用,否则我会得到 django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_project.settings")
import django
django.setup()

另外,我将它添加到我的 django 项目的 __init__.py 中,它会自动发现应用名称,因此可以复制/粘贴:

import os


def setup():
    module = os.path.split(os.path.dirname(__file__))[-1]
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", ".settings".format(module))
    import django
    django.setup()

那我就可以了:

from <app> import setup
setup()

【讨论】:

谢谢,显然从 Django 1.7 开始需要调用 setup()。 init 中的 setup() 不错,喜欢! 现在应该是正确答案了。唯一适合我的解决方案。 我注意到两件事:1)当多个文件中有设置时会引发错误,2)在 models.py 中调用 setup() 时不起作用,否则很好回答 @yvesva 你不应该从你的models.py中调用它。这是为了从外部脚本初始化 django。不要在您的标准 django 应用程序调用流程中使用它。将它放在多个文件中应该没有任何问题吗?只要函数获取的模块路径合适,它就可以工作。我的印象是您没有正确执行此操作。【参考方案5】:

这是 Django 版本 > 1.4 的答案:

from django.core.management import settings
from myproject.myproject import settings as project_settings

if not settings.configured:
  settings.configure(default_settings=project_settings)

【讨论】:

【参考方案6】:

适用于 DJANGO 1.11

上面的解决方案不起作用,但给了我一个错误:

django.core.exceptions.AppRegistryNotReady:应用尚未加载。

对我来说,here 解决了:

import os
from django.core.wsgi import get_wsgi_application

os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'
application = get_wsgi_application()

【讨论】:

【参考方案7】:

对于 Django 1.9 或更高版本,您可以使用此:

import sys
import os
import django

sys.path.append('your_project_directory')
os.environ['DJANGO_SETTINGS_MODULE'] = 'your_project.settings'
django.setup()

from yourapp.models import your_model

所以您可以将对象用作相同的 django 对象:

from myapp.models. import Locations
all_locations = Locations.object.all()
first_location = Locations.object.get(id=1)
print first_location.name()
first_location.save()

【讨论】:

这对我有用!姜戈 2.0。为什么我们需要将路径附加到我们的项目目录中?关于 django.setup() 的高级功能有什么好的信息吗? @timbram - 你发现了吗?有没有办法在 sublime text 3 或 atom 等文本编辑器中自动执行此操作? 这是唯一适用于 Windows 上最新 LTS 版本 (3.2) 的解决方案。【参考方案8】:

至少从 Django 1.11 开始,您的主应用程序包含一个 wsgi 模块,该模块在导入时进行必要的设置。假设 myproject/myproject 是您的 settings.py 所在的位置,在您的脚本中只需导入:

from myproject.wsgi import application

【讨论】:

【参考方案9】:

如果你得到:

django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.

试试:

import os
from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.settings')
application = get_wsgi_application()

【讨论】:

我在 Django 中使用一个独立的脚本来导入模型。我尝试了上述技术,但出现以下错误 RuntimeError: populate() is not reentrant @AR7 你找到解决这个错误的方法了吗?我遇到了同样的问题。 我认为当您多次调用 get_wsgi_application() 时会发生重入错误。【参考方案10】:

试试:

os.environ["DJANGO_SETTINGS_MODULE"] = "mysite.settings"

如果os.environ.setdefault 不起作用。 (Windows 10、python3.6.4、django 2.0.3)

【讨论】:

【参考方案11】:

正如 Stavros 指出的here,您只需复制 wsgi.py 并将其放在脚本的开头即可。除了设置 DJANGO_SETTINGS_MODULE 之外,您还需要获取应用程序。希望能帮助到你。它适用于 django 2.1.5。

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'revochem.settings')

application = get_wsgi_application()

【讨论】:

【参考方案12】:

对于 django >= 2.0 进行这 2 个导入就足够了

from your_project_path import settings as your_project_settings
from django.core.management import settings

那么你就可以from my_app.models import MyModel

并使用您的模型MyModel

【讨论】:

以上是关于用于 Django 应用程序的 Python 脚本,无需使用 manage.py shell 即可访问模型的主要内容,如果未能解决你的问题,请参考以下文章

Django将Python对象从视图传递到模板中的Javascript脚本

Django/AngularJS:如何从我的 AngularJS 脚本访问我的 Python 上下文项

在线运行python脚本(django)[关闭]

在 django 视图中使用 subprocess.Popen() 执行 python 脚本

Pytho之Django

从独立的python脚本访问postgresql上的django数据库