Як перезавантажити модулі в оболонці 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.