Як перезавантажити модулі в оболонці django?


90

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

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


2
Вам слід оновити це запитання, щоб позначити правильну відповідь "django-extensions".
woodardj

1
Тільки поки це насправді не спрацює для мене. У мене встановлено розширення, і жодне з мого коду не перезавантажується автоматично, і я не бачу жодної згадки про автоматичне перезавантаження в документах shell_plus. Здається, у команді runserver_plus є перезавантажувач, але це не те, що я шукаю.
Mad Wombat

Відповіді:


37

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

manage.py shell_plus --notebook

Це відкриє блокнот IPython у вашому веб-браузері. Напишіть свій код там у комірці, імпортуйте тощо та запустіть його.

Коли ви змінюєте модулі, просто клацніть пункт меню ноутбука «Ядро-> Перезапустити»

Ось, ваш код тепер використовує ваші модифіковані модулі.


30
«Просто користуйся блокнотом на пітоні» - це не відповідь на запитання OP.
J__

Цей метод, хоча і не є автоматичним, як% автозавантаження, працює надійніше, ніж автозавантаження. перезапуск ядра гарантує, що всі комірки ноутбука отримують повністю перезавантажені модулі. Крім того, ви можете перезапустити та запустити всі комірки, якщо ви вирішите.
Антон І. Сіпос

72

Я б запропонував використовувати розширення автозавантаження 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 не можна перезавантажувати, а тому не можна завантажувати автоматично.

3
Якщо ви використовуєте django's /manage.py shell_plus... якщо ви введете %load_ext autoreloadі потім %autoreload 2, моделі будуть автоматично перезавантажені.
Fusion

Дивовижно, ти зробив мені день
Шамсул Арефін Саджиб

Зауважте, що для цього вам потрібно встановити ipython. Дивіться , наприклад , stackoverflow.com/a/47170195/50899
Rabarberski

38

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


40
Я використовую shell_plus, і мої моделі не перезавантажуються автоматично, я чогось пропускаю?
Дієго Пончано

30
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

37

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

python shell.py shell <test.py

Тож я можу внести зміни, зберегти та запустити цю команду ще раз, поки не виправлю все, що намагаюся виправити.


2
Приємно і просто. Одну нотатку додайте exit()внизу файлу py, щоб очистити оболонку Django. Дякую.
Марк

Просте та елегантне рішення. Хороша робота.
nikoskip

25

Здається, загальний консенсус щодо цієї теми полягає в тому, що python reload () відстій, і немає хорошого способу зробити це.


Невірно. Відповідь @ dongweiming вище - це рішення, і її слід прийняти як найкращу відповідь.
Джозеф Шиді,

3
Кілька коментарів до його відповіді говорять, що shell_plus не перезавантажує моделі
Mad Wombat

1
Я щойно випробував його, і він не перезавантажується. Крім того, а як щодо немодельного коду, який я імпортую вручну?
Божевільний вомбат

Класи в програмі, яку я зараз використовую, чудово перезавантажують (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-розширення 1.5.9.
Mad Wombat


5

Моє рішення цього незручного випливає далі. Я використовую 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

Сподіваюся, це допоможе. Звичайно, це для налагодження.

На ура


2

Використовуйте 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( docs ), буде автоматично завантажено!

Зверніть увагу, що якщо ваша оболонка перебуває у налагоджувачі (колишньому pdb.set_trace()), коли ви зберігаєте файл, це може заважати перезавантаженню.


1
Дякую за відповідь. Хоча ви можете зауважити, що я запитав це у 2010 році. Я радий знати, що через вісім років автоперезавантаження нарешті працює в shell_plus :)
Mad Wombat

1

Замість того, щоб запускати команди з оболонки Django, ви можете налаштувати команду керування так і повторити її кожен раз.


0

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

У цій команді ви можете налаштувати купу місцевих жителів, як хочете, а потім потрапити в інтерактивну оболонку.

import code

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

Немає перезавантаження, але простий і менш надокучливий спосіб інтерактивної перевірки функціональності django.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.