Làm cách nào để thực thi tập lệnh Python từ trình bao Django?


247

Tôi cần phải thực thi một tập lệnh Python từ trình bao Django. Tôi đã thử:

./manage.py shell << my_script.py

Nhưng nó không hoạt động. Nó chỉ chờ tôi viết một cái gì đó.


Đây không phải là cách làm djangoviệc, bạn thực sự muốn làm gì?
danodonovan

2
my_script.pychứa một vài thao tác trên một trong những mẫu Django của tôi. Tôi đã làm điều này trước đây nhưng tôi không thể nhớ chính xác như thế nào.

Câu trả lời:


388

Phần <<sai, sử dụng <thay thế:

$ ./manage.py shell < myscript.py

Bạn cũng có thể làm:

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

Đối với python3, bạn sẽ cần sử dụng

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

17
Đối với tôi, điều này chỉ thực hiện dòng đầu tiên của kịch bản. Điều duy nhất hiệu quả là kết hợp cả hai phương pháp:./manage.py shell <<EOF\ execfile('myscript.py') \EOF
Steve Bennett

Nó không hoạt động nữa với Python 3+. Bất kỳ ý tưởng để thay thế này?
David D.

4
@DavidD. Sự thay thế được đưa ra trong câu trả lời này tại đây
peter2108

11
Một giải pháp khác có vẻ hoạt động cho cả Python 2.x và 3.x là echo 'import myscript' | python manage.py shell. Tôi đã thấy điều này có thể hữu ích cho các tập lệnh nhanh và bẩn mà bạn chỉ cần chạy một lần mà không phải trải qua quá trình tạo manage.pylệnh rườm rà .
Atul Varma

1
nếu bạn đang làm điều này trên vỏ điện Windows: Get-Content myscript.py | .\manage.py shell
Aditya Wirayudha

219

Bạn không nên làm điều đó từ shell- và điều này được dự định vì bạn thực sự không nên thực thi các tập lệnh ngẫu nhiên từ môi trường django (nhưng có nhiều cách khác, hãy xem các câu trả lời khác).

Nếu đây là tập lệnh mà bạn sẽ chạy nhiều lần, bạn nên thiết lập tập lệnh này dưới dạng lệnh tùy chỉnh, tức là

 $ ./manage.py my_command

để làm điều này tạo ra một tập tin trong một subdir của managementcommandscủa bạn app, ví dụ:

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

và trong tệp này xác định lệnh tùy chỉnh của bạn (đảm bảo rằng tên của tệp là tên của lệnh bạn muốn thực hiện ./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

9
Một lần nữa đây là câu trả lời tốt nhất. Vì django 1.8 NoArgsCommandkhông được dùng nữa. Trang này đưa ra một ví dụ hoạt động: docs.djangoproject.com/en/1.9/howto/custom-manloyment-commands/ chủ
Ger

2
Theo nhận xét của trước đó, cho nó để làm việc cho tôi rằng tôi cần phải thay đổi def handle_noargs(self, **options):để def handle(self, **options):.
James

Liên kết thú vị ở đây để hỗ trợ cho câu trả lời này và các tài liệu.
Mattia Paterna

1
Để làm cho nó hoạt động thay đổi def handle(self, **options):như nhận xét của James.
Omar Gonzales

Câu trả lời tao nhã. Cảm ơn rất nhiều
Tessaracter 6/11/19

103

Đối với bất kỳ ai sử dụng Django 1.7+, có vẻ như chỉ cần nhập mô-đun cài đặt là không đủ.

Sau khi đào bới, tôi đã tìm thấy câu trả lời Stack Overflow này: https://stackoverflow.com/a/23241093

Bây giờ bạn cần phải:

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

Không làm như trên, tôi đã nhận được một django.core.exceptions.AppRegistryNoReadylỗi.

Tệp tập lệnh của tôi nằm trong cùng thư mục với dự án django của tôi (nghĩa là trong cùng thư mục với Manage.py)


2
Thiết lập của tôi có tệp cài đặt đã được tham chiếu trong DJANGO_SETTINGS_MODULEbiến môi trường. Với điều đó là đủ để chỉ: import django ; django.setup()dưới 1.7.
Taylor Edmiston

1
Với django 1.7+, đây sẽ là câu trả lời được chấp nhận :)
acidjunk

Đây chắc chắn là câu trả lời chính xác cho Django 1.9.x. Không chạy django.setup()sẽ không cho phép tập lệnh truy cập vào các mô hình Django, thậm chí không nhập chúng!
glarrain

Trong một virtualenv bạn có thể đơn giản import django; django.setup().
Người dùng3759685

1
Bạn đã làm cho ngày của tôi! Cảm ơn cho bài viết này. tôi đã nhận được creazy trên cần tây vì tôi không thể thực hiện các nhiệm vụ trên quản

68

Tôi đến bữa tiệc muộn nhưng tôi hy vọng rằng phản hồi của tôi sẽ giúp được ai đó: Bạn có thể làm điều này trong tập lệnh Python của mình:

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

phần còn lại của công cụ của bạn ở đây ....


3
Cũng lưu ý rằng bạn có thể bỏ sys.path.appendnội dung miễn là bạn hiểu DJANGO_SETTINGS_MODULESđúng (ví dụ: nếu bạn có một tập lệnh nằm ngay phía trên trang web gốc của bạn, bạn có thể làm os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings').
mgasms

Tôi đã kết thúc việc này sys.path.append(os.getcwd()), nó hoạt động khi tôi ở trong thư mục dự án của mình, DJANGO_SETTINGS_MODULE của tôi là chính xác và tôi cố gắng chạy một kịch bản nhập mô hình, lượt xem, v.v.
Danilo Cabello

Vâng, nhưng bạn không thể chạy nó từ bất cứ đâu!
e-nouri

Điều này không phù hợp với tôi với django 1.6 - Tôi có một ứng dụng. Tôi đã thiết lập đường dẫn của mình để bao gồm thư mục dự án django và thiết lập các cài đặt dự án. Nhưng khi tôi thử và nhập ứng dụng của mình với "từ shoppinglist.models nhập Danh sách mua sắm", tôi gặp phải một lỗi mà nó không thể tìm thấy mô hình. Dòng nhập tương tự đó hoạt động từ bên trong shell Manage.txt. Có ý kiến ​​gì không?
frankster

33

runscripttừ phần mở rộng django

python manage.py runscript scripty.py

Một mẫu script.pyđể kiểm tra nó:

from django.contrib.auth.models import User
print(User.objects.values())

Được đề cập tại: http://django-extensions.readthedocs.io/en/latest/command_extensions.html và được ghi lại tại:

python manage.py runscript --help

Có một hướng dẫn quá .

Đã thử nghiệm trên Django 1.9.6, django-phần mở rộng 1.6.7.


1
Đây là câu trả lời tốt nhất nếu bạn đang sử dụng django-extensions(bạn nên). Lưu ý: Có vẻ như runscriptsử dụng django tiêu chuẩn shell. Sẽ thật tuyệt vời nếu nó được sử dụng shell_plus(cũng trong các tiện ích mở rộng) vì vậy bạn không phải nhập mọi thứ cho các tập lệnh đơn giản.
Grokpot

12

Nếu IPython có sẵn ( pip install ipython) thì ./manage.py shellsẽ tự động sử dụng shell của nó và sau đó bạn có thể sử dụng lệnh ma thuật %run:

%run my_script.py

Làm việc như người ở!
Roel

Điều này có lợi thế hơn runscriptlà nó hoạt động với các tập lệnh bên ngoài dự án / gói và không phàn nàn như thế nàyTypeError: the 'package' argument is required to perform a relative import for
smido

8

Bạn chỉ có thể chạy tập lệnh với bộ DJANGO_SETTINGS_MODULEbiến môi trường. Đó là tất cả những gì cần thiết để thiết lập môi trường Django-shell.

Điều này hoạt động trong Django> = 1,4



6

nếu bạn không có nhiều lệnh trong tập lệnh của mình, hãy sử dụng nó:

manage.py shell --command="import django; print(django.__version__)"

Tài liệu Django


4

Như các câu trả lời khác chỉ ra nhưng không nói rõ, những gì bạn thực sự cần không nhất thiết phải thực thi tập lệnh của bạn từ trình bao Django, mà là để truy cập các ứng dụng của bạn mà không cần sử dụng trình bao Django .

Điều này khác rất nhiều phiên bản Django so với phiên bản Django. Nếu bạn không tìm thấy giải pháp của mình trên chuỗi này, hãy trả lời tại đây - tập lệnh Django để truy cập các đối tượng mô hình mà không cần sử dụng trình quản lý shell - hoặc các tìm kiếm tương tự có thể giúp bạn.

Tôi đã phải bắt đầu my_command.py với

import os,sys
sys.path.append('/path/to/myproject')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.file")
import django
django.setup()

import project.app.models
#do things with my models, yay

và sau đó chạy python3 my_command.py

(Django 2.0.2)


Điều này vẫn hoạt động cho Django 3.0. Tôi đã thay thế sys.path.append('/path/to/myproject')bằng BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))và `sys.path.append (BASE_DIR)`. Cũng đừng quên kích hoạt env ảo của bạn trước khi thực hiện lệnh!
mrj

3
import os, sys, django
os.environ["DJANGO_SETTINGS_MODULE"] = "settings"
sys.path.insert(0, os.getcwd())

django.setup()

1
Bạn có thể vui lòng chỉnh sửa giải thích tại sao mã này trả lời câu hỏi theo cách khác với một số câu trả lời trước đó rất giống nhau không? Câu trả lời chỉ có mã không được khuyến khích , vì họ không dạy giải pháp.
Nathan Tuggy 16/07/2015

2

Lưu ý, phương pháp này đã không được chấp nhận cho các phiên bản gần đây của django! (> 1.3)

Một câu trả lời khác, bạn có thể thêm nó vào đầu my_script.py

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

và thực hiện my_script.pychỉ với python trong thư mục mà bạn có settings.pynhưng đây là một chút hack.

$ python my_script.py

1

Nếu bạn muốn chạy trong BG tốt hơn nữa:

nohup echo 'exec(open("my_script.py").read())' | python manage.py shell &

Đầu ra sẽ ở nohup.out



0

Hãy thử điều này nếu bạn đang sử dụng môi trường ảo: -

python quản lý shell

để sử dụng các lệnh đó, bạn phải ở trong môi trường ảo. cho việc sử dụng này: -

làm việc vir_env_name

ví dụ :-

dc@dc-comp-4:~/mysite$ workon jango
(jango)dc@dc-comp-4:~/mysite$ python manage.py shell
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> 

Lưu ý : - Ở đây mysite là tên trang web của tôi và jango là tên môi trường ảo của tôi


0

đã đến đây với cùng một câu hỏi như OP và tôi đã tìm thấy câu trả lời yêu thích của mình chính xác là lỗi trong câu hỏi, cũng hoạt động trong Python 3:

./manage.py shell <<EOF
import my_script
my_script.main()
EOF

0

Mặt khác, nó thực thi cái này:

echo 'execfile("/path_to/myscript.py")' | python manage.py shell --settings=config.base

Điều này đang hoạt động trên Python2.7 và Django1.9


0

Nếu bạn muốn thực thi tập lệnh khởi động (ví dụ: nhập một số mô hình django để tương tác với chúng) và vẫn ở trong trình bao django:

PYTHONSTARTUP=my_script.py python manage.py shell

0

Trình bao django là cách tốt để thực thi mô-đun python với môi trường django, nhưng không phải lúc nào cũng dễ dàng và mệt mỏi để nhập mô-đun và thực hiện các chức năng bằng tay đặc biệt là không tự động hoàn thành. Để giải quyết vấn đề này, tôi đã tạo một tập lệnh shell nhỏ "rancript.sh" cho phép bạn tận dụng tối đa tính năng tự động hoàn thành và lịch sử nhật ký của bảng điều khiển Linux.

NB: Sao chép tệp runcript.sh vào dự án gốc và đặt quyền thực thi (chmod + x)

Ví dụ: Tôi muốn chạy hàm python có tên show (a, b, c) trong mô-đun do_somethings.py trong myapp / do_folder /

Cách django tiêu chuẩn (quản lý shell):

python3 manage.py shell
 > from myapp.do_folder import do_somethings
 > do_somethings.show("p1", "p2"  , 3.14159)

Với tập lệnh (rancript.sh):

./runscript.sh myapp/do_folder/do_somethings.py show p1 p2 3.14159

Kịch bản không bị giới hạn về số lượng đối số. Tuy nhiên, chỉ các đối số của kiểu nguyên thủy được hỗ trợ (int, float, chuỗi)


Xin chào, có lẽ runscripttừ django-extensionsgói làm tương tự, hãy kiểm tra nó django-extensions.readthedocs.io/en/latest/runscript.html
frost-nzcr4

Cảm ơn bạn frost-nzcr4. Vâng, thực sự, phần mở rộng này hoạt động, nhưng tôi thấy nó bị giới hạn trong thư mục srcipts và chỉ ở hàm run (). Với srcipt của tôi, bạn có thể thực thi một chức năng ở bất kỳ đâu trong bất kỳ thư mục nào.
Martin13

0

Đi dự tiệc muộn. Nhưng điều này có thể hữu ích cho một ai đó.

Tất cả bạn cần là kịch bản của bạn và django-extensionscài đặt.

Chỉ cần chạy shell_pluscó sẵn django_extensionsvà nhập tập lệnh mà bạn đã viết.

Nếu tập lệnh của bạn scpt.pynằm trong thư mục, folbạn có thể chạy tập lệnh như sau.

python manage.py shell_plus

và chỉ cần nhập tập lệnh của bạn bên trong shell như sau.

>>> from fol import scpt

-1

django.setup () dường như không hoạt động.

dường như cũng không được yêu cầu.

Điều này một mình làm việc.

import os, django, glob, sys, shelve
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myProject.settings")

1
django.setup () chắc chắn là cần thiết để khởi động môi trường Django.
colm.anseo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.