如何从Django shell执行Python脚本?

350

我需要从Django shell中执行一个Python脚本。我尝试了:

./manage.py shell << my_script.py

但是它没有起作用。它只是在等我写点什么。


这不是 django 的工作方式,你实际上想要做什么? - danodonovan
4
my_script.py 包含了一些对我 Django 模型的操作。我之前已经做过这些操作,但是我不太记得具体怎么做了。 - user2429940
27个回答

541

这里的<<部分是错误的,应该使用<代替:

$ ./manage.py shell < myscript.py

你也可以这样做:

$ ./manage.py shell
...
>>> execfile('myscript.py')

对于Python3,您需要使用:

>>> exec(open('myscript.py').read())

18
对我而言,这只执行了脚本的第一行。唯一有效的方法是结合这两种方法:./manage.py shell <<EOF\ execfile('myscript.py') \EOF - Steve Bennett
4
@DavidD. 这个答案中提供了替代方案 这里 - peter2108
18
另一个似乎适用于Python 2.x和3.x的解决方案是“echo 'import myscript' | python manage.py shell”。我发现这对于您只需要运行一次的快速脚本非常有用,而无需经历创建“manage.py”命令的繁琐过程。 - Atul Varma
我该如何以这种方式使用命令行参数来运行 myscript.py - Sean Letendre
1
如果你正在Windows PowerShell上执行此操作:Get-Content myscript.py | .\manage.py shell - Aditya Wirayudha
显示剩余7条评论

295

shell 中执行随机脚本并不被推荐 - 这是有意为之的,因为你不应该在 Django 环境中执行随机脚本(但是还有其他方法可以绕过此限制,请参见其他答案)。

如果这是一个需要多次运行的脚本,则将其设置为自定义命令是个好主意。

 $ ./manage.py my_command

为此,在您的appmanagementcommands子目录中创建一个文件,例如:

my_app/
    __init__.py
    models.py
    management/
        __init__.py
        commands/
            __init__.py
            my_command.py
    tests.py
    views.py

在这个文件中定义你的自定义命令(确保文件名是你想要从./manage.py执行的命令的名称)

from django.core.management.base import BaseCommand

class Command(BaseCommand):
    def handle(self, **options):
        # now do the things that you want with your models here

13
这是最好的答案。自从Django 1.8以来,“NoArgsCommand”已被弃用。此页面提供了一个可行的示例:https://docs.djangoproject.com/en/1.9/howto/custom-management-commands/#module-django.core.management - Ger
2
根据之前的评论,为了让它对我起作用,我需要将def handle_noargs(self, **options):更改为def handle(self, **options): - James
1
要使其工作,请按照詹姆斯的评论更改为 def handle(self, **options): - Omar Gonzales
1
优雅的回答。非常感谢。 - Trect
1
这是正确的答案。 - Francesco Marchetti-Stasi
显示剩余4条评论

128

对于使用Django 1.7+的任何人来说,似乎仅仅导入设置模块是不够的。

在一些挖掘之后,我找到了这个Stack Overflow答案:https://dev59.com/kmEh5IYBdhLWcg3wKQnY#23241093

现在你需要:

import os, django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
django.setup()
# now your code can go here...

如果不执行上述操作,我会遇到django.core.exceptions.AppRegistryNoReady错误。

我的脚本文件与Django项目位于同一个目录中(即与manage.py在同一个文件夹中)。


2
我的设置已经在DJANGO_SETTINGS_MODULE环境变量中引用了设置文件。只需要在1.7版本下执行import django; django.setup()即可。 - Taylor D. Edmiston
3
使用 Django 1.7+,这应该是被接受的答案 :) - acidjunk
1
这绝对是Django 1.9.x的正确答案。不运行django.setup()将无法让脚本访问Django模型,甚至无法导入它们! - glarrain
2
你让我开心了!感谢这篇文章。因为我无法在management.call_command上执行任务,所以我对celery感到很疯狂:D :D :D - user10000033
1
这对于开始制作在Django环境中运行的独立脚本非常有帮助。您可能还想要import syssys.path.insert(0, ".")以及sys.path.insert(0, "../lib")或类似的内容,以便能够访问位于起始目录之外的不同位置的库。设置模块名称只是路径上到settings.py的目录名称,用.而不是/分隔。 - NeilG
显示剩余3条评论

73

虽然我来晚了,但我希望我的回答能帮助到某些人: 您可以在Python脚本中执行此操作:

import sys, os
sys.path.append('/path/to/your/django/app')
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from django.conf import settings

您的其余内容放在此处...


3
请注意,只要正确设置了 DJANGO_SETTINGS_MODULE(例如,如果你有一个在站点根目录上面的脚本,你可以使用 os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'),就不需要再添加 sys.path.append 的内容。 - mgalgs
最终我做了sys.path.append(os.getcwd()),这样在我进入我的项目目录、我的DJANGO_SETTINGS_MODULE正确并且我尝试运行一个导入models、views等的脚本时会有效。 - Danilo Cabello
是的,但你不能从任何地方运行它! - e-nouri
这在我的django 1.6上不起作用 - 我有一个应用程序。我已经设置了我的路径以包括django项目目录并设置了项目设置。但是当我尝试使用“from shoppinglist.models import ShoppingList”导入我的应用程序时,会出现找不到模型的错误。同样的导入行可以在manage.py shell中工作。有什么想法吗? - frankster

50

1
如果您已经在使用django-extensions(您应该这样做),那么这是最好的答案。注意:看起来runscript使用标准的Django shell。如果它使用shell_plus(也在扩展中),那将是非常棒的,这样您就不必为简单的脚本导入所有内容了。 - grokpot

16
如果 IPython 可用(pip install ipython),则 ./manage.py shell 将自动使用它的shell,然后您可以使用魔术命令%run
%run my_script.py

这种方法比runscript更有优势,因为它可以处理项目/包之外的脚本,并且不会出现类似于“TypeError:the 'package' argument is required to perform a relative import”的错误提示。 - smido

15

@AtulVarma在不工作的被接受的答案下提供了非常有用的评论:

echo 'import myscript' | python manage.py shell

1
太好了!我在评论中错过了它。感谢您把它放在这里。 - Anupam
1
以及变体cat ./my_script.py | python manage.py shell - ddelange
1
这应该是正确的答案,只需要一行代码就可以工作!对于任何寻找此功能的人来说,“import script”可以在模块内部,例如“import mysite.script”。非常好用。 - Daniel

14

1
这对我大部分都有效。只是想补充一下,如果你的脚本中有很多命令:python manage.py shell --command="\cat script_name.py`"` - wile_e8

10

虽然我来晚了,但我希望我的回答能帮到某个人:

步骤1:导入

import mysite.asgi

步骤二:只需输入以下命令即可执行 Python 脚本:

python test.py

假设 test.py 文件长这样:

import mysite.asgi

from polls.models import GMD_TABLE
print ( [obj.gt_GMD_name for obj in GMD_TABLE.objects.all()] )

最终结果: The result will be:

['ISHWARDI', 'JHENAIDHA', 'HVDC CIRCLE']

['ISHWARDI', 'JHENAIDHA', 'HVDC CIRCLE']是GMD_TABLE的值。


应该使用哪个版本的Django? - Dmitry Chebakov
@DmitryChebakov Django 版本:3.2.6 - Engr Md. Ashraful Haque

8

您只需设置环境变量DJANGO_SETTINGS_MODULE并运行脚本即可。这就是设置Django shell环境所需的全部步骤。

在Django >= 1.4中适用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接