Python 无需使用manage.py shell即可访问模型对象的Django脚本

Python 无需使用manage.py shell即可访问模型对象的Django脚本,python,django,django-models,Python,Django,Django Models,我正在编写一个脚本,将一些模型对象导入到django应用程序使用的数据库中。过去,我通过运行/manage.py shell然后导入myscript解决了这个问题。我相信有更好的办法。我希望能够使用python scriptname.py从我的硬盘上的任何地方调用脚本,并且在该脚本的前几行中,它将执行任何必要的导入/其他操作,以便它能够访问模型对象并像使用manage.py shell运行一样运行 要实现这一点,我需要在脚本中添加什么 编辑: 根据@Melug的回答,添加了动态设置Python路

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

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

编辑:

根据@Melug的回答,添加了动态设置Python路径以解决问题的“我的硬盘上的任何地方”部分:

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

您需要首先设置django环境:

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

最后导入您的模型,一切都像django一样进行。

我认为最好的方法是创建您的模型。然后您可以从任何地方调用
manage.py

因为Django 1.4,您应该避免使用
setup\u 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)

为了让模型也加载,我必须将其与相结合,否则我会得到
django.core.exceptions.AppRegistryNotReady:模型还没有加载

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_project.settings")
import django
django.setup()
另外,我将其添加到django项目的
\uuuuu init\uuuuuuu.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.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)

适用于DJANGO 1.11

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

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

对于我来说,解决方案来自:

import os
from django.core.wsgi import get_wsgi_application

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

对于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()

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

来自myproject.wsgi导入应用程序的

如果您得到:

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

尝试:

os.environ[“DJANGO\u设置\u模块”]=“mysite.SETTINGS”

如果操作系统环境设置默认值不起作用。(Windows 10、python3.6.4、django 2.0.3)

正如Stavros所指出的,您可以复制wsgi.py并将其放在脚本的开头。除了设置DJANGO_设置_模块外,您还需要获取应用程序。希望能有帮助。它在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()

对于django>=2.0,完成这两个导入就足够了

from your_project_path import settings as your_project_settings
from django.core.management import settings
然后您可以从my_应用程序执行
。模型导入MyModel


从长远来看,使用您的型号
MyModel

更好的选择。我同意,这是一条路要走。它并不比创建一个独立的脚本困难多少,而且更加健壮。虽然确实如此,但有时仍然需要使用来自其他脚本的django模型。
setup\u environ(settings)
自django 1.4以来就被弃用了!我在下面的帖子中展示了一个包含示例的替代方案。只有在我在导入os后立即将os.Enviro.setdefault(“DJANGO_设置_模块”、“您的_项目_名称.SETTINGS”)移动到行中之后,这才对我有效。否则,这是一个更好的解决方案。说得好,彼得!可能一些模型导入只在
os.environ.setdefault(…)
行之后工作。我在我的帖子中重新安排了导入内容,现在它应该适用于所有人。附言:如果你更喜欢这个解决方案,请投赞成票。谢谢我可以在没有外部设置文件的情况下执行此操作吗?也就是说,我想在一个脚本中构建模型、连接和所有内容。我不在乎视图…@isaalw我不相信没有设置文件你就可以做到这一点。如果你有办法,请告诉我们。顺便说一句,我的
settings.py
不处理任何视图,它处理连接参数、调试模式等标志。所有视图都在
myapp/views.py
中定义,并且可以通过
url.py
中定义的url模式访问。我几乎有了它,我只需要将设置文件设置为某个值。目前我已将其设置为空字符串。DATABASES={}已正确设置。然后:
os.environ[“DJANGO_SETTINGS_MODULE”]='
SETTINGS.configure(**locals())
这一切都来自DJANGO.db导入模型的
谢谢,显然需要调用setup(),因为DJANGO 1.7。init中的setup()很好,喜欢!现在这应该是正确的答案。唯一适合我的解决方案。我注意到两件事:1)在多个文件中有设置时会抛出错误,2)在models.py中调用setup()时不起作用,否则很好answer@yvesva你不应该从你的models.py中调用这个。这用于从外部脚本初始化django。不要在标准django应用程序调用流中使用此选项。把它放在多个文件中应该没有问题吧?只要函数得到的模块路径合适,它就可以工作。我得到的印象是你做得不对。我正在Django中使用一个独立的脚本来导入模型。我尝试了上述技术,得到了以下错误RuntimeError:populate()不是reentrant@AR7你找到解决这个错误的方法了吗?我也遇到了同样的问题。我认为当您多次调用get_wsgi_应用程序()时,会发生reentrat错误。这对我很有效!Django 2.0。为什么我们需要在项目目录中附加路径?关于django.setup()的高级功能有什么好的信息吗?@timbram-你发现了吗?在sublime text 3或atom这样的文本编辑器中,有没有一种方法可以自动执行此操作
from your_project_path import settings as your_project_settings
from django.core.management import settings