장고 셸에서 모듈을 다시로드하는 방법은 무엇입니까?


91

저는 Django와 함께 일하고 있으며 항상 Django 셸을 사용합니다. 성가신 부분은 Django 서버가 코드 변경 사항에 대해 다시로드하는 동안 셸은 그렇지 않으므로 테스트중인 메서드를 변경할 때마다 셸을 종료하고 다시 시작하고 모든 모듈을 다시 가져와야한다는 것입니다. 필요, 필요한 모든 변수를 다시 초기화하십시오. iPython 히스토리가 이것에 대한 많은 타이핑을 저장하지만 여전히 고통입니다. django 개발 서버와 같은 방식으로 django shell 자동 새로 고침을 만드는 방법이 있습니까?

reload ()에 대해 알고 있지만 많은 모델을 가져오고 일반적으로 from app.models import *구문을 사용 하므로 reload ()는별로 도움이되지 않습니다.


2
이 질문을 업데이트하여 "django-extensions"답변이 올바른 것으로 표시해야합니다.
woodardj 2013

1
실제로 작동하기 전까지는 아닙니다. 확장 프로그램이 설치되어 있고 코드가 자동으로 다시로드되지 않으며 shell_plus 문서에서 자동 다시로드에 대한 언급이 없습니다. runserver_plus 명령에 리 로더가있는 것 같지만 제가 찾고있는 것은 아닙니다.
Mad Wombat 2015

답변:


37

dongweiming이 위에서 언급 한 것처럼 django-extensions 프로젝트를 사용하는 것이 좋습니다. 그러나 'shell_plus'관리 명령 대신 다음을 사용하십시오.

manage.py shell_plus --notebook

웹 브라우저에서 IPython 노트북이 열립니다. 셀, 가져 오기 등의 코드를 작성하고 실행하십시오.

모듈을 변경할 때 노트북 메뉴 항목 'Kernel-> Restart'를 클릭하십시오.

이제 코드가 수정 된 모듈을 사용하고 있습니다.


31
"그냥 파이썬 노트북을 사용하라"는 OP의 질문에 대한 답이 아닙니다.
J__

이 방법은 % autoreload와 같이 자동은 아니지만 autoreload보다 더 안정적으로 작동합니다. 커널을 다시 시작하면 노트북의 모든 셀이 완전히 다시로드 된 모듈을 얻을 수 있습니다. 또한 선택하면 모든 셀을 다시 시작하고 실행할 수 있습니다.
Anton I. Sipos

75

IPython autoreload 확장 프로그램을 사용하는 것이 좋습니다 .

./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 가지 자동 다시로드 전략을 사용 하여 일부 가져 오기가 새로 고쳐지는 것을 방지 할 수도 있습니다 .

% autoreload

  • 이제 모든 모듈 (% aimport에 의해 제외 된 모듈 제외)을 자동으로 다시로드합니다.

% autoreload 0

  • 자동 새로 고침을 사용 중지합니다.

% autoreload 1

  • 입력 된 Python 코드를 실행하기 전에 매번 % aimport로 가져온 모든 모듈을 다시로드합니다.

% autoreload 2

  • 입력 된 Python 코드를 실행하기 전에 매번 모든 모듈 (% aimport에 의해 제외 된 모듈 제외)을 다시로드하십시오.

% aimport

  • 자동으로 가져 오거나 가져 오지 않을 모듈을 나열합니다.

% aimport foo

  • 'foo'모듈을 가져 와서 % autoreload 1에 대해 자동으로 다시로드되도록 표시하십시오.

% aimport -foo

  • 자동으로 다시로드되지 않도록 'foo'모듈을 표시합니다.

이것은 일반적으로 내 사용에 적합하지만 몇 가지주의 사항이 있습니다.

  • 코드 개체를 교체하는 것이 항상 성공하는 것은 아닙니다. 클래스의 @property를 일반 메서드로 변경하거나 메서드를 멤버 변수로 변경하면 문제가 발생할 수 있습니다 (그러나 이전 개체에서만).
  • 다시로드되기 전에 모듈에서 제거 된 (예 : monkey-patching을 통해) 기능은 업그레이드되지 않습니다.
  • C 확장 모듈은 다시로드 할 수 없으므로 자동으로 다시로드 할 수 없습니다.

3
django를 사용하는 경우 /manage.py shell_plus...를 입력 %load_ext autoreload한 다음 을 입력 %autoreload 2하면 모델이 자동으로 다시로드됩니다.
Fusion

놀라운, 당신은 내 일했다
샴술 Arefin Sajib

분명히 ipython을 설치해야합니다. 예를 들어 stackoverflow.com/a/47170195/50899
Rabarberski

39

내 해결책은 코드를 작성하고 파일에 저장 한 다음 다음을 사용하는 것입니다.

파이썬 manage.py 쉘 <test.py

따라서 수정하려는 항목을 수정할 때까지 변경하고 해당 명령을 저장하고 다시 실행할 수 있습니다.


2
멋지고 간단합니다. 참고로 exit()Django 셸을 깔끔하게 종료하려면 py 파일의 맨 아래에 추가하십시오 . 고마워.
Marc

간단하고 우아한 솔루션. 잘 했어.
nikoskip

38

django-extensions 프로젝트 에서 제공하는 manage.py shell_plus 명령을보십시오 . 쉘 시작시 모든 모델 파일을로드합니다. 수정 사항을 자동으로 다시로드하지만 종료 할 필요는 없습니다. 직접 호출 할 수 있습니다.


40
shell_plus를 사용하는데 모델이 자동으로 다시로드되지 않습니다. 누락 된 것이 있습니까?
Diego Ponciano 2014-06-06

30
shell_plus는 모델을 다시로드하지 않으므로 질문에 대한 답이 아닙니다.
aljabear

5
말했듯이 shell_plus는 모델을 다시로드하지 않습니다.
zenperttu

2
어쩌면 내가 뭔가를 놓치고 있지만 shell_plus는 나를 위해 아무것도 다시로드하지 않습니다. 시작시 모든 모델을로드하므로 편리하지만 그게 전부입니다.
Mad Wombat 2015

14
shell_plus는 autoreload 모듈을 사용하여 모듈을 다시로드 할 수 있습니다. '% load_ext autoreload'를 입력 한 다음 '% autoreload 2'를 입력하십시오. ipython.org/ipython-doc/3/config/extensions/autoreload.html
bbrame

25

이 주제에 대한 일반적인 합의는 파이썬 reload ()가 형편없고이를 수행하는 좋은 방법이 없다는 것입니다.


틀 렸습니다. 위의 @dongweiming의 답변이 해결책이며 최선의 답변으로 받아 들여 져야합니다.
Joseph Sheedy 2015

3
shell_plus이 모델 다시로드하지 않는 그의 대답의 말에 여러 의견
미친 웜뱃

1
방금 직접 테스트했는데 다시로드되지 않습니다. 게다가 손으로 가져 오는 비 모델 코드는 어떻습니까?
Mad Wombat

내가 사용하는 앱의 클래스는 평범한 비 장고 모델 모듈과 그 안의 클래스를 포함하여 (Python 3.4.3, Django 1.9b1, django-extensions 1.5.9) 훌륭하게 다시로드합니다. 이 답변이 나온 지 5 년이 지났고 많은 발전이있었습니다.
Joseph Sheedy 2015

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)

들어 파이썬 3.x를 , '다시로드'는 사용하여 가져올 수 있어야합니다 :

from importlib import reload

도움이 되었기를 바랍니다. 물론 디버그 용입니다.

건배.



4

ipython 구성과 함께 shell_plus 를 사용하십시오 . 이것은 autoreloadshell_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에서 작동 후 그
미친 웜뱃


0

정확히 당신이 원하는 것은 아니지만, 나는 이제 테스트와 조작을위한 관리 명령을 직접 구축하는 경향이 있습니다.

명령에서 원하는 방식으로 많은 로컬을 설정하고 나중에 대화 형 셸로 이동할 수 있습니다.

import code

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

재로드는 없지만 django 기능을 대화식으로 테스트하는 쉽고 덜 성가신 방법입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.