如何为 Django 应用程序创建一个 Python 脚本,该脚本可以在不使用 manager. py shell 的情况下访问模型?

我正在编写一个脚本,将一些模型对象导入到 django 应用程序使用的数据库中。在过去,我通过运行 ./manage.py shellimport 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)
69570 次浏览

You need to setup django environment first:

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

At last import your models, everything goes just like django.

I think the best way is to create your custom management command(s). Then you can call manage.py <yourcommand> from anywhere.

Since Django 1.4 you should avoid using setup_environ(settings) (post by Melug) because it is deprecated. Use the following instead and you will be able to access your model

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..

Here is an example to access and modify your model:

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

Example model:

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

To get models loaded too, I had to combine this with this answer, otherwise I get django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet

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

As an extra, I add this to the __init__.py of my django projects, it will automatically discover the app name so it is copy/paste-able:

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

Then I can just do:

from <app> import setup
setup()

Here is the answer for Django versions > 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)

FOR DJANGO 1.11

Upper solutions did not work, but gave me an error:

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

For me solution from here worked out:

import os
from django.core.wsgi import get_wsgi_application


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

For Django version 1.9 or later you can use this:

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

so you can use object as same django object:

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

Since at least Django 1.11, your main app includes a wsgi module that does the neccessary setup on import. Assuming myproject/myproject is where your settings.py is, in your script just import:

from myproject.wsgi import application

If you get:

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

Try:

import os
from django.core.wsgi import get_wsgi_application


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

Try:

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

if os.environ.setdefault doesn't work. (Windows 10, python3.6.4, django 2.0.3)

As Stavros pointed out here, you can just copy the wsgi.py and put it at the beginning of you script. Besides setting up DJANGO_SETTINGS_MODULE, you also need to get the applications. Hope it helps. It works for me at 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()

for django >= 2.0 it is enough to do these 2 imports

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

then you can do just from my_app.models import MyModel

and work with your Model MyModel

Many of the above answers are correct, but don't reference the official documentation.

First you need to configure settings or set the DJANGO_SETTINGS_MODULE envrionment variable

from django.conf import settings
if not settings.configured:
settings.configure(myapp_defaults, DEBUG=True)

The docs then specify:

After you’ve either set DJANGO_SETTINGS_MODULE or called configure() you’ll need to call django.setup() to load your settings and populate Django’s application registry. For example:

import django from django.conf
import settings from myapp
import myapp_defaults


settings.configure(default_settings=myapp_defaults, DEBUG=True)
django.setup()


# Now this script or any imported module can use any part of Django it needs. from myapp import models ```

The docs also include an important caveat:

django.setup() may only be called once.

Therefore, avoid putting reusable application logic in standalone scripts so that you have to import from the script elsewhere in your application. If you can’t avoid that, put the call to django.setup() inside an if block:

if __name__ == '__main__':
import django
django.setup()