Как перезагрузить модули в оболочке Django? - PullRequest
70 голосов
/ 22 сентября 2010

Я работаю с Django и все время использую оболочку Django.Раздражает то, что, хотя сервер Django перезагружается при изменении кода, оболочка этого не делает, поэтому каждый раз, когда я изменяю метод, который я тестирую, мне нужно выходить из оболочки и перезапускать ее, повторно импортировать все модули, которые янужно, заново инициализировать все переменные, которые мне нужны, и т. д. Хотя история iPython экономит много времени на этом, это все еще является проблемой.Есть ли способ сделать автозагрузку оболочки django таким же образом, как это делает сервер разработки django?

Я знаю о reload (), но я импортирую много моделей и обычно использую синтаксис from app.models import *, поэтому перезагрузите() не очень помогает.

Ответы [ 10 ]

42 голосов
/ 25 мая 2013

посмотрите на команду manage.py shell_plus, предоставленную проектом django-extensions . Он загрузит все файлы вашей модели при запуске оболочки. и автоматически перезагружать любые изменения, но выход не требуется, вы можете напрямую позвонить туда

39 голосов
/ 14 декабря 2016

Я бы предложил использовать IPython расширение автозагрузки .

./manage.py shell

In [1]: %load_ext autoreload
In [2]: %autoreload 2

И теперь все импортированные модули будут обновлены перед оценкой.

In [3]: from x import print_something
In [4]: print_something()
Out[4]: 'Something'

 # Do changes in print_something method in x.py file.

In [5]: print_something()
Out[5]: 'Something else'

Работает также, если что-то было импортировано до %load_ext autoreload команды.

./manage.py shell
In [1]: from x import print_something
In [2]: print_something()
Out[2]: 'Something'

 # Do changes in print_something method in x.py file.

In [3]: %load_ext autoreload
In [4]: %autoreload 2
In [5]: print_something()
Out[5]: 'Something else'

Также возможно предотвратить обновление некоторых импортов с помощью команды %aimport и 3 стратегий автоматической перезагрузки:

% автоперезагрузки

  • Перезагрузить все модули (кроме исключенных% aimport) автоматически сейчас.

% автозагрузка 0

  • Отключить автоматическую перезагрузку.

% автозагрузка 1

  • Перезагрузите все модули, импортированные с% aimport, каждый раз перед выполнением набранный код Python.

% автозагрузка 2

  • Перезагружать все модули (кроме исключенных% aimport) каждый раз перед выполнением набранного кода Python.

% aimport

  • Список модулей, которые должны быть автоматически импортированы или не должны быть импортирован.

% импорт foo

  • Импортировать модуль «foo» и пометить его для автоматической загрузки для% autoreload 1

% aimport -foo

  • Отметьте модуль 'foo', чтобы он не загружался автоматически.

Обычно это хорошо подходит для моего использования, но есть несколько кавет:

  • Замена объектов кода не всегда успешна: изменение @property в классе на обычный метод или метод на переменную-член может вызвать проблемы (но только для старых объектов).
  • Функции, которые удалены (например, с помощью «мартышки») из модуля до его перезагрузки, не обновляются.
  • Модули расширения C не могут быть перезагружены, и поэтому не могут быть автоматически перезагружены.
30 голосов
/ 11 декабря 2013

Я рекомендую использовать проект django-extensions, как указано выше в dongweiming. Но вместо просто команды управления 'shell_plus' используйте:

manage.py shell_plus --notebook

Откроется блокнот IPython в вашем веб-браузере. Запишите свой код в ячейку, импортируйте и т. Д. И запустите его.

Когда вы меняете свои модули, просто щелкните по пункту меню ноутбука 'Kernel-> Restart'

Итак, ваш код теперь использует ваши модифицированные модули.

28 голосов
/ 06 ноября 2014

Я решил написать код и сохранить в файл, а затем использовать:

python manage.py shell

Итак, яможете внести изменения, сохранить и снова запустить эту команду, пока я не исправлю все, что пытаюсь исправить.

25 голосов
/ 29 сентября 2010

Похоже, что общее мнение по этой теме заключается в том, что python reload () отстой, и нет хорошего способа сделать это.

4 голосов
/ 28 октября 2016

Мое решение для этого неудобно следующее. Я использую IPython.

$ ./manage.py shell
> import myapp.models as mdls   # 'mdls' or whatever you want, but short...
> mdls.SomeModel.objects.get(pk=100)
> # At this point save some changes in the model
> reload(mdls)
> mdls.SomeModel.objects.get(pk=100)

Для Python 3.x 'reload' должен быть импортирован с использованием:

from importlib import reload

Надеюсь, это поможет. Конечно, для отладки.

Приветствие.

4 голосов
/ 23 сентября 2010

Перезагрузка () не работает в оболочке Django без некоторых хитростей. Вы можете проверить эту тему на мой ответ и конкретно:

Как перезагрузить модуль модели Django с помощью интерактивного интерпретатора через "manage.py shell"?

1 голос
/ 26 апреля 2019

Используйте shell_plus с конфигурацией ipython. Это включит autoreload до того, как shell_plus автоматически импортирует что-либо.

pip install django-extensions
pip install ipython
ipython profile create

Отредактируйте свой профиль ipython (~/.ipython/profile_default/ipython_config.py):

c.InteractiveShellApp.exec_lines = ['%autoreload 2']
c.InteractiveShellApp.extensions = ['autoreload']

Откройте оболочку - обратите внимание, что вам не нужно включать --ipython:

python manage.py shell_plus

Теперь все, что определено в SHELL_PLUS_PRE_IMPORTS или SHELL_PLUS_POST_IMPORTS ( документы ), будет автоматически перезагружено!

Обратите внимание, что если ваша оболочка находится в отладчике (например, pdb.set_trace()), то при сохранении файла она может помешать перезагрузке.

1 голос
/ 03 декабря 2013

Вместо запуска команд из оболочки Django вы можете настроить команду управления примерно так и выполнять ее каждый раз.

0 голосов
/ 11 декабря 2013

Не совсем то, что вы хотите, но сейчас я склонен создавать команды управления для тестирования и работы с вещами.

В команде вы можете настроить группу локальных пользователей так, как вы хотите, и затем перейти в интерактивную оболочку.

import code

class Command(BaseCommand):
  def handle(self, *args, **kwargs):
     foo = 'bar'
     code.interact(local=locals())

Нет перезагрузки, но простой и менее раздражающий способ интерактивного тестирования функциональности django.

...