Estou trabalhando com Django e uso o shell Django o tempo todo. A parte chata é que enquanto o servidor Django recarrega nas mudanças de código, o shell não, então toda vez que eu faço uma mudança em um método que estou testando, preciso sair do shell e reiniciá-lo, reimportar todos os módulos que preciso, reinicializar todas as variáveis de que preciso etc. Embora o histórico do iPython economize muita digitação nisso, ainda é uma dor. Existe uma maneira de fazer o django shell recarregar automaticamente, da mesma forma que o servidor de desenvolvimento django faz?
Eu sei sobre reload (), mas eu importo muitos modelos e geralmente uso from app.models import *
sintaxe, então reload () não ajuda muito.
Respostas:
Eu recomendo usar o projeto django-extensions como afirmado acima por dongweiming. Mas em vez de apenas o comando de gerenciamento 'shell_plus', use:
Isso abrirá um notebook IPython em seu navegador da web. Escreva seu código lá em uma célula, suas importações etc. e execute-o.
Quando você mudar seus módulos, apenas clique no item de menu do notebook 'Kernel-> Reiniciar'
Pronto, seu código agora está usando seus módulos modificados.
fonte
Eu sugiro usar a extensão autoreload IPython .
./manage.py shell In [1]: %load_ext autoreload In [2]: %autoreload 2
E a partir de agora todos os módulos importados seriam atualizados antes de serem avaliados.
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'
Funciona também se algo foi importado antes do
%load_ext autoreload
comando../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'
Também é possível evitar que algumas importações sejam atualizadas com o
%aimport
comando e 3 estratégias de autoreload:Isso geralmente funciona bem para o meu uso, mas existem algumas cavetas:
fonte
/manage.py shell_plus
... se você digitar%load_ext autoreload
e então%autoreload 2
, os modelos serão automaticamente recarregados.Minha solução para isso é escrever o código, salvar em um arquivo e usar:
Assim, posso fazer a alteração, salvar e executar esse comando novamente até corrigir o que estou tentando consertar.
fonte
exit()
ao final do arquivo py para sair do shell do Django de maneira mais limpa. THX.veja o comando manage.py shell_plus fornecido pelo projeto django-extensions . Ele irá carregar todos os seus arquivos de modelo na inicialização do shell. e autoreload qualquer modificação, mas não precisa sair, você pode chamar direto para lá
fonte
Parece que o consenso geral sobre este tópico é que python reload () é uma merda e não há uma boa maneira de fazer isso.
fonte
Minha solução para esse inconveniente é a seguinte. Estou usando 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)
Para Python 3.x , 'reload' deve ser importado usando:
from importlib import reload
Espero que ajude. Claro que é para fins de depuração.
Felicidades.
fonte
Reload () não funciona no shell do Django sem alguns truques. Você pode verificar este tópico na e minha resposta especificamente:
Como você recarrega um módulo de modelo Django usando o interpretador interativo via "manage.py shell"?
fonte
Use shell_plus com uma configuração ipython. Isso será habilitado
autoreload
antes que o shell_plus importe qualquer coisa automaticamente.Edite seu perfil ipython (
~/.ipython/profile_default/ipython_config.py
):c.InteractiveShellApp.exec_lines = ['%autoreload 2'] c.InteractiveShellApp.extensions = ['autoreload']
Abra um shell - observe que você não precisa incluir
--ipython
:Agora, qualquer coisa definida em
SHELL_PLUS_PRE_IMPORTS
ouSHELL_PLUS_POST_IMPORTS
( docs ) será carregada automaticamente!Observe que se seu shell estiver em um depurador (ex
pdb.set_trace()
), quando você salvar um arquivo, ele pode interferir no recarregamento.fonte
Em vez de executar comandos no shell do Django, você pode configurar um comando de gerenciamento como este e executá- lo novamente a cada vez.
fonte
Usando uma combinação de 2 respostas para isso, eu vim com uma abordagem simples de uma linha.
Você pode executar o shell django com -c que irá executar os comandos que você passar, no entanto, ele fecha imediatamente após a execução do código.
O truque é configurar o que você precisa, execute code.interact (local = locals ()) e reinicie o shell de dentro do código que você passou. Como isso:
python manage.py shell -c 'import uuid;test="mytestvar";import code;code.interact(local=locals())'
Para mim, eu só queria o método de inspeção da rica biblioteca. Apenas algumas linhas:
python manage.py shell -c 'import code;from rich import pretty;pretty.install();from rich import inspect;code.interact(local=locals())'
Finalmente, a cereja do bolo é um pseudônimo
alias djshell='python manage.py shell -c "import code;from rich import pretty;pretty.install();from rich import inspect;code.interact(local=locals())"'
Agora, se eu iniciar meu shell e disser, quero inspecionar a classe de formulário, recebo esta bela saída:
fonte
Não é exatamente o que você quer, mas agora tenho a tendência de construir comandos de gerenciamento para testar e mexer nas coisas.
No comando, você pode configurar vários locais da maneira que quiser e depois colocá-los em um shell interativo.
import code class Command(BaseCommand): def handle(self, *args, **kwargs): foo = 'bar' code.interact(local=locals())
Sem recarregar, mas uma maneira fácil e menos irritante de testar interativamente a funcionalidade do django.
fonte