web-dev-qa-db-de.com

Wie lade ich Module in die Django-Shell?

Ich arbeite mit Django und benutze Django Shell die ganze Zeit. Das Ärgerliche daran ist, dass, während der Django-Server die Codeänderungen neu lädt, die Shell dies nicht tut. Jedes Mal, wenn ich eine von mir getestete Methode ändere, muss ich die Shell beenden und neu starten und alle Module neu importieren Sie müssen alle Variablen neu initialisieren, die ich brauche usw. Während die iPython-Historie eine Menge Tipparbeit bei diesem Vorgang spart, ist dies immer noch ein Schmerz. Gibt es eine Möglichkeit, Django Shell automatisch neu zu laden, genauso wie der Entwicklungsserver von Django?

Ich kenne reload (), aber ich importiere viele Modelle und verwende from app.models import *-Syntax. Reload () ist also keine große Hilfe.

68
Mad Wombat

Ich empfehle, das Django-Extensions-Projekt wie oben beschrieben von Dongweiming zu verwenden. Verwenden Sie jedoch anstelle des Verwaltungsbefehls 'Shell_plus' Folgendes:

manage.py Shell_plus --notebook

Dadurch wird ein IPython-Notizbuch in Ihrem Webbrowser geöffnet. Schreiben Sie Ihren Code dort in eine Zelle, Ihre Importe usw. und führen Sie ihn aus. 

Wenn Sie Ihre Module ändern, klicken Sie einfach auf den Menüpunkt "Kernel> Neustart".

Ihr Code verwendet nun Ihre modifizierten Module.

27
mpaf

schauen Sie sich den Befehl shell.py Shell_plus an, der vom Projekt Django-extensions bereitgestellt wird. Beim Start von Shell werden alle Modelldateien geladen. und laden Sie jede beliebige Änderung automatisch, brauchen Sie jedoch nicht zu beenden. Sie können dort direkt anrufen

43
dongweiming

Ich würde vorschlagen, IPython Autoreload Erweiterung zu verwenden.

./manage.py Shell

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

Ab sofort werden alle importierten Module vor der Auswertung aktualisiert.

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'

Funktioniert auch, wenn vor dem %load_ext autoreload-Befehl etwas importiert wurde.

./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'

Es ist auch möglich zu verhindern, dass einige Importe mit dem Befehl %aimport und drei Autoreload-Strategien aktualisiert werden:

% Autoreload

  • Laden Sie alle Module (mit Ausnahme der von% aimport ausgeschlossenen) automatisch neu jetzt. 

% Autoreload 0

  • Deaktivieren Sie das automatische Nachladen. 

% Autoreload 1

  • Laden Sie alle mit% aimport importierten Module vor jeder Ausführung neu der eingegebene Python-Code. 

% Autoreload 2

  • Laden Sie jedes Mal alle Module neu (außer die von% aimport ausgeschlossenen) vor dem Ausführen des eingegebenen Python-Codes. 

% aimport

  • Listen Sie Module auf, die automatisch importiert werden sollen oder nicht importiert. 

% aimport foo

  • Importieren Sie das Modul „foo“ und markieren Sie es für% autoreload 1 als automatisch geladen

% aimport -foo

  • Markieren Sie das Modul „foo“, um nicht automatisch geladen zu werden.

Dies funktioniert im Allgemeinen gut für meine Verwendung, aber es gibt einige Cavetas:

  • Das Ersetzen von Code-Objekten ist nicht immer erfolgreich: Das Ändern einer @ -Eigenschaft in einer Klasse in eine gewöhnliche Methode oder einer Methode in eine Member-Variable kann zu Problemen führen (jedoch nur bei alten Objekten).
  • Funktionen, die vor dem Neuladen (z. B. durch Affen-Patching) aus einem Modul entfernt wurden, werden nicht aktualisiert.
  • C-Erweiterungsmodule können nicht erneut geladen werden und können daher nicht automatisch geladen werden.
35
bodolsog

Es scheint, dass der allgemeine Konsens zu diesem Thema darin besteht, dass Python reload () saugt und es gibt keinen guten Weg, dies zu tun.

25
Mad Wombat

Meine Lösung dazu ist, dass ich den Code schreibe und in eine Datei speichere und dann verwende:

python manage.py Shell <test.py

So kann ich die Änderung vornehmen, speichern und den Befehl erneut ausführen, bis ich alles korrigiert habe, was ich beheben möchte.

25
Erik

Reload () funktioniert in Django Shell nicht ohne ein paar Tricks. Sie können diesen Thread na und meine Antwort genau überprüfen:

Wie kann ein Django-Modellmodul mithilfe des interaktiven Interpreters über "manage.py Shell" geladen werden?

4

Meine Lösung für dieses Unbequeme folgt. Ich benutze 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)

Ich hoffe es hilft. Natürlich dient es zu Debug-Zwecken.

Prost.

4
Roque

Anstelle der Ausführung von Befehlen von der Django-Shell aus können Sie einen Verwaltungsbefehl wie so einrichten und diesen Befehl jedes Mal erneut ausführen.

1
thomaspaulb

Verwenden Sie Shell_plus mit einer ipython-Konfiguration. Dadurch wird autoreload aktiviert, bevor Shell_plus automatisch etwas importiert.

pip install Django-extensions
pip install ipython
ipython profile create

Bearbeiten Sie Ihr Ipython-Profil (~/.ipython/profile_default/ipython_config.py):

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

Öffnen Sie eine Shell - beachten Sie, dass Sie --ipython nicht einschließen müssen:

python manage.py Shell_plus

Jetzt wird alles, was in Shell_PLUS_PRE_IMPORTS oder Shell_PLUS_POST_IMPORTS ( docs ) definiert ist, automatisch geladen!

0
andorov

Nicht genau das, was Sie wollen, aber ich neige jetzt dazu, mir Verwaltungsbefehle zum Testen und Fummeln mit Dingen zu erstellen.

Im Befehl können Sie eine Reihe von Einheimischen nach Ihren Wünschen einrichten und anschließend in einer interaktiven Shell ablegen.

import code

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

Kein Nachladen, aber eine einfache und weniger störende Möglichkeit, die Django-Funktionalität interaktiv zu testen.

0
toabi