Как перезагрузить модули в оболочке django?

92

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

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

Безумный вомбат
источник
2
Вы должны обновить этот вопрос, чтобы отметить правильный ответ "django-extensions".
woodardj
1
Нет, пока это не сработает для меня. У меня установлены расширения, и ни один из моих кодов не перезагружается автоматически, и я не вижу никаких упоминаний об автоматической перезагрузке в документации shell_plus. Кажется, что в команде runserver_plus есть перезагрузчик, но это не то, что я ищу.
Mad Wombat

Ответы:

38

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

manage.py shell_plus --notebook

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

Когда вы меняете модули, просто щелкните пункт меню записной книжки «Ядро-> Перезагрузить».

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

MPAF
источник
32
«Просто используйте записную книжку на Python» - это не ответ на вопрос ОП.
J__
1
Этот метод, хотя и не автоматический, как% autoreload, работает более надежно, чем автоматическая перезагрузка. перезапуск ядра гарантирует, что все ячейки в ноутбуке будут полностью перезагружены. Кроме того, вы можете перезапустить и запустить все ячейки, если захотите.
Антон И. Сипос
76

Я бы предложил использовать расширение автозагрузки 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команды и трех стратегий автоматической перезагрузки:

% autoreload

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

% autoreload 0

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

% autoreload 1

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

% autoreload 2

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

% прицеливания

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

% aimport foo

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

% aimport -foo

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

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

  • Замена объектов кода не всегда бывает успешной: изменение @property в классе на обычный метод или метода на переменную-член может вызвать проблемы (но только в старых объектах).
  • Функции, которые удаляются (например, путем установки патчей) из модуля перед его перезагрузкой, не обновляются.
  • Модули расширения C не могут быть перезагружены, и поэтому не могут быть перезагружены автоматически.
Bodolsog
источник
3
Если вы используете django /manage.py shell_plus... если вы наберете, %load_ext autoreloadа затем %autoreload 2, модели будут автоматически перезагружены.
Fusion
Удивительно, ты сделал мой день
Шамсул Арефин Саджиб
Обратите внимание, что, очевидно, для этого вам потребуется установить ipython. См., Например, stackoverflow.com/a/47170195/50899
Rabarberski
куда поставить этот% autoreload? Из ответа
непонятно
40

Мое решение - я пишу код и сохраняю его в файл, а затем использую:

оболочка python manage.py <test.py

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

Эрик
источник
2
Красиво и просто. Одно примечание: добавьте exit()в конец файла py, чтобы упростить выход из оболочки Django. Спасибо.
Marc
Простое и элегантное решение. Молодец.
nikoskip
38

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

Dongweiming
источник
41
Я использую shell_plus, и мои модели не перезагружаются автоматически, мне что-то не хватает?
Diego Ponciano
31
shell_plus не перезагружает модели, поэтому это не отвечает на вопрос.
aljabear
5
как сказано, shell_plus не перезагружает модели.
zenperttu
2
Может, мне чего-то не хватает, но shell_plus для меня ничего не перезагружает. Он загружает все модели при запуске, что удобно, но на этом все.
Mad Wombat
14
shell_plus МОЖЕТ перезагружать модули, используя модуль автозагрузки. Введите "% load_ext autoreload", а затем "% autoreload 2" - см. Ipython.org/ipython-doc/3/config/extensions/autoreload.html
bbrame
25

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

Безумный вомбат
источник
Неправильно. Ответ @ dongweiming выше - это решение, и его следует принять как лучший ответ.
Джозеф Шиди,
3
В нескольких комментариях к его ответу говорится, что shell_plus не перезагружает модели
Mad Wombat
1
Я только что тестировал сам и не перезагружается. Кроме того, как насчет немодельного кода, который я импортирую вручную?
Mad Wombat
Классы в приложении, которое я сейчас использую, отлично перезагружаются (Python 3.4.3, Django 1.9b1, django-extensions 1.5.9), включая простой модуль, не относящийся к модели django, и класс внутри него. Прошло 5 лет с момента этого ответа, и произошло много изменений.
Джозеф Шиди
1
Я пробовал это на своей установке 40 минут назад, и shell_plus для меня ничего не перезагружает. Django 1.7.10, python 3.4.3, django-extensions 1.5.9.
Mad Wombat
6

Мое решение для этого неудобства следующее. Я использую 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

Используйте 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_IMPORTSor SHELL_PLUS_POST_IMPORTS( docs ), будет автоматически перезагружено!

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

Андоров
источник
2
Спасибо за ответ. Однако вы можете заметить, что я спросил об этом в 2010 году. Я рад узнать, что через восемь лет автоперезагрузка наконец-то работает в shell_plus :)
Mad Wombat
1

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

LittleGreen
источник
1

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

Вы можете запустить оболочку django с помощью -c, которая будет запускать переданные вами команды, однако она завершается сразу после запуска кода.

Хитрость заключается в том, чтобы настроить то, что вам нужно, запустить code.interact (local = locals ()), а затем повторно запустить оболочку из кода, который вы передаете. Как это:

python manage.py shell -c 'import uuid;test="mytestvar";import code;code.interact(local=locals())'

Мне просто нужен метод проверки из богатой библиотеки. Всего несколько строк:

python manage.py shell -c 'import code;from rich import pretty;pretty.install();from rich import inspect;code.interact(local=locals())'

Наконец, вишенка на вершине - это псевдоним

alias djshell='python manage.py shell -c "import code;from rich import pretty;pretty.install();from rich import inspect;code.interact(local=locals())"'

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

Джон Дж.
источник
0

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

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

import code

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

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

тоаби
источник