Python/Django TypeError: для относительного импорта требуется аргумент "пакет"

После многих лет написания на C и C++ я чувствую себя немного глупо, когда дело доходит до Python и Django. Я не могу заставить что-то простое работать. Я допускаю, что ошибка обсуждалась в ряде постов.

Я начал изучать некоторые учебные пособия по django, поэтому запустил "django-admin startproject mysite", который создал папку "mysite".

Я установил django_extensions, так что теперь я пытаюсь использовать его "runcript". У меня есть более сложный скрипт, который я хочу запустить позже, но сейчас я пытаюсь вызвать простой пользовательский скрипт, который я нашел в сети с помощью этого механизма, т.е.

mysimplescript.py:

def run(*script_args):
print script_args

Он расположен в папке 'scripts', поэтому моя структура выглядит следующим образом, где внешний каталог mysite/ root является просто контейнером для моего проекта:

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py
    scripts
        __init__.py
        mysimplescript.py

Когда я запускаю скрипт следующим образом, я получаю ошибку относительного импорта.

python manage.py runscript .scripts.mysimplescript.py --script-args  
Testing 123

/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core 
/management/base.py:265:  RemovedInDjango110Warning: 
OptionParser usage for Django management commands is deprecated, use 
ArgumentParser instead

RemovedInDjango110Warning)
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core  
/management/__init__.py", line 353, in execute_from_command_line
utility.execute()
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core 
/management/__init__.py", line 345, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/ 
django_extensions/management/email_notifications.py", line 63, in   
run_from_argv
super(EmailNotificationCommand, self).run_from_argv(argv)
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core 
/management/base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/ 
django_extensions/management/email_notifications.py", line 75, in execute
super(EmailNotificationCommand, self).execute(*args, **options)
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core 
/management/base.py", line 399, in execute
output = self.handle(*args, **options)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/ 
django_extensions/management/utils.py", line 57, in inner
ret = func(self, *args, **kwargs)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/ 
django_extensions/management/commands/runscript.py", line 163, in handle
modules = find_modules_for_script(script)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/ 
django_extensions/management/commands/runscript.py", line 146, in  
find_modules_for_script
mod = my_import(nn)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/ 
django_extensions/management/commands/runscript.py", line 99, in my_import
importlib.import_module(mod)
File "/usr/lib64/python2.7/importlib/__init__.py", line 30, in import_module
raise TypeError("relative imports require the 'package' argument")
TypeError: relative imports require the 'package' argument

Если я включу отладку, то я вижу следующее @ runcript.py #99: Проверьте.scripts.mysimplescript.scripts.py

Изначально запустив несколько уроков по django, было установлено следующее:

./mysite/wsgi.py:os.environ.setdefault("DJANGO_SETTINGS_MODULE",  
"mysite.settings")
./manage.py:    os.environ.setdefault("DJANGO_SETTINGS_MODULE", 
"mysite.settings")
./mysite/settings.py:ROOT_URLCONF = 'mysite.urls'

Некоторые обсуждения по теме, например [1]: упаковка Python для относительного импорта и [2]: как сделать относительный импорт в Python? предложите добавить main.py во внешний каталог mysite/.

По сути, я все же хочу вызвать скрипт через расширения django, используя:

python manage.py runscript  <some_script>

Просто еще один момент. Если я уроню "." перед папкой т.е.

python manage.py runscript scripts.mysimplescript.py --script-args Testing 
123

тогда я получаю следующую ошибку:

No (valid) module for script 'scripts.mysimplescript.py' found

все же 'mysimplescript.pyc' генерируется.

Может кто-то помочь мне, пожалуйста? Как я могу заставить Python распознать пакет? Заранее спасибо.

3 ответа

Пример в документации - сохранить скрипт как scripts/delete_all_questions.py, а затем запустить его с

python manage.py runscript delete_all_questions

В вашем случае ваш скрипт scripts/mysimplescript.pyтак что вы запускаете его с

python manage.py runscript mysimplescript --script-args Testing 123

Обратите внимание, что вы используете имя модуля mysimplescriptтак что не стоит включать .py, Приложение django_extensions предполагает, что сценарии находятся в scripts каталог, так что не включайте это тоже.

Относительный импорт может выполняться только из пакета Python. Директория, которую вы используете для относительного импорта: 1. Содержит файл init.py 2. Доступен для PYTHONPATH (объявлен как путь или подкаталог другого каталога, у которого есть init.py и который находится на пути)

Другими словами, относительный путь не будет работать в скрипте, если вы не вызовете весь пакет:

$ python -m manage.py runscript mystie.scripts.mysimplescript

Это будет работать..

python manage.py runscript mysimplescript --script-args Testing 
123
Другие вопросы по тегам