在Django中使用`settings/dev.py`而非`settings.py`运行独立脚本查询模型
注意这里提到的 settings/dev.py
,而不是一个 settings.py
文件,以及在 my_app
里的 script.py
,这是一个 Django(1.4.3) 项目的结构:
.
├── my_project
│ ├── my_app
│ │ ├── __init__.py
│ │ ├── models.py
│ │ ├── tests.py
│ │ ├── views.py
│ │ └── script.py
│ ├── __init__.py
│ ├── settings
│ │ ├── dev.py
│ │ ├── __init__.py
│ │ └── prod.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── requirements.txt
之前我只有一个 settings.py 文件,而没有 settings 文件夹,那时候我可以顺利运行下面的脚本,没有任何错误:
script.py:
###################################################################
# set up for making it possible to run a model query from my script.
###################################################################
import os
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)))
from django.core.management import setup_environ
import settings
setup_environ(settings)
####################################################################
from my_app.models import MyModel
all_entries = MyModel.objects.all()
顺便说一下,我是从 这篇文章的第二种方法中得到这个想法的,我的设置比原文多了几行,因为我的 script.py
在 my_app
文件夹里,而不是直接放在 my_project
文件夹下。
现在我 使用的是 settings/dev.py
而不是 settings.py
,所以我在脚本的最后两行做了如下修改:
import settings.dev
import setup_environ(settings.dev)
但是当我 现在运行我的脚本时,却出现了这个错误:
Traceback (most recent call last):
File "my_script.py", line 12, in <module>
all_entries = MyModel.objects.all()
File "/home/my_username/.virtualenvs/my_project/local/lib/python2.7/site-packages/django/db/models/manager.py", line 131, in get
return self.get_query_set().get(*args, **kwargs)
File "/home/my_username/.virtualenvs/my_project/local/lib/python2.7/site-packages/django/db/models/query.py", line 358, in get
clone = self.filter(*args, **kwargs)
File "/home/my_username/.virtualenvs/my_project/local/lib/python2.7/site-packages/django/db/models/query.py", line 624, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/home/my_username/.virtualenvs/my_project/local/lib/python2.7/site-packages/django/db/models/query.py", line 642, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/home/my_username/.virtualenvs/my_project/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1250, in add_q
can_reuse=used_aliases, force_having=force_having)
File "/home/my_username/.virtualenvs/my_project/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1122, in add_filter
process_extras=process_extras)
File "/home/my_username/.virtualenvs/my_project/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1304, in setup_joins
field, model, direct, m2m = opts.get_field_by_name(name)
File "/home/my_username/.virtualenvs/my_project/local/lib/python2.7/site-packages/django/db/models/options.py", line 311, in get_field_by_name
cache = self.init_name_map()
File "/home/my_username/.virtualenvs/my_project/local/lib/python2.7/site-packages/django/db/models/options.py", line 341, in init_name_map
for f, model in self.get_all_related_m2m_objects_with_model():
File "/home/my_username/.virtualenvs/my_project/local/lib/python2.7/site-packages/django/db/models/options.py", line 429, in get_all_related_m2m_objects_with_model
cache = self._fill_related_many_to_many_cache()
File "/home/my_username/.virtualenvs/my_project/local/lib/python2.7/site-packages/django/db/models/options.py", line 443, in _fill_related_many_to_many_cache
for klass in get_models(only_installed=False):
File "/home/my_username/.virtualenvs/my_project/local/lib/python2.7/site-packages/django/db/models/loading.py", line 181, in get_models
self._populate()
File "/home/my_username/.virtualenvs/my_project/local/lib/python2.7/site-packages/django/db/models/loading.py", line 64, in _populate
self.load_app(app_name, True)
File "/home/my_username/.virtualenvs/my_project/local/lib/python2.7/site-packages/django/db/models/loading.py", line 86, in load_app
app_module = import_module(app_name)
File "/home/my_username/.virtualenvs/my_project/local/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
ImportError: No module named my_project.my_app
这个错误为什么会出现? 我该如何在 Django 中使用 settings/dev.py
来运行我的脚本,而不是 settings.py
?
1 个回答
如果你想在 Django 环境中运行一个脚本,最简单的方法就是创建一个 ./manage.py
的子命令,像这样:
from django.core.management.base import BaseCommand
from my_app.models import MyModel
class Command(BaseCommand):
help = 'runs your code in the django environment'
def handle(self, *args, **options):
all_entries = MyModel.objects.all()
for entry in all_entries:
self.stdout.write('entry "%s"' % entry)
关于这个,文档提供了很好的解释。
不过,你可以通过以下方式指定一个设置文件来运行:
$ django-admin.py runserver --settings=settings.dev
这将使用 dev
中的设置来运行测试服务器,但我担心你的问题可能比这更复杂。我不建议你随便修改 manage.py
文件,因为这可能会导致不一致和将来的麻烦。
另外要注意,dev.py
如果要这样做,应该是一个完整的设置文件。我个人建议使用这样的结构:
|-settings
| |- __init__.py
| |- base.py
| |- dev.py
| |- prod.py
把所有通用设置放在 base.py
中,然后把 dev.py
的第一行改成类似这样的内容:
# settings/dev.py
from .base import *
DEBUG = True
...
编辑
如果你只是想测试一下,为什么不试试:
$ ./manage.py shell
或者使用你的开发设置:
$ django-admin.py shell --settings=settings.dev
这样会为你设置所有的操作系统环境变量和 settings.py
,然后你就可以进行测试或调试:
>>> from my_app.models import MyModel
>>> all_entries = MyModel.objects.all()
>>> for entry in all_entries:
... print entry