How to reload modules in django shell?

后端 未结 11 1110
面向向阳花
面向向阳花 2020-12-22 18:38

I am working with Django and use Django shell all the time. The annoying part is that while the Django server reloads on code changes, the shell does not, so every time I ma

相关标签:
11条回答
  • 2020-12-22 19:11

    It seems that the general consensus on this topic, is that python reload() sucks and there is no good way to do this.

    0 讨论(0)
  • 2020-12-22 19:17

    I recommend using the django-extensions project like stated above by dongweiming. But instead of just 'shell_plus' management command, use:

    manage.py shell_plus --notebook
    

    This will open a IPython notebook on your web browser. Write your code there in a cell, your imports etc. and run it.

    When you change your modules, just click the notebook menu item 'Kernel->Restart'

    There you go, your code is now using your modified modules.

    0 讨论(0)
  • 2020-12-22 19:17

    My solution for this inconvenient follows. I am using 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)
    

    For Python 3.x, 'reload' must be imported using:

    from importlib import reload
    

    Hope it helps. Of course it is for debug purposes.

    Cheers.

    0 讨论(0)
  • 2020-12-22 19:18

    I'd suggest use IPython autoreload extension.

    ./manage.py shell
    
    In [1]: %load_ext autoreload
    In [2]: %autoreload 2
    

    And from now all imported modules would be refreshed before evaluate.

    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'
    

    Works also if something was imported before %load_ext autoreload command.

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

    There is possible also prevent some imports from refreshing with %aimport command and 3 autoreload strategies:

    %autoreload

    • Reload all modules (except those excluded by %aimport) automatically now.

    %autoreload 0

    • Disable automatic reloading.

    %autoreload 1

    • Reload all modules imported with %aimport every time before executing the Python code typed.

    %autoreload 2

    • Reload all modules (except those excluded by %aimport) every time before executing the Python code typed.

    %aimport

    • List modules which are to be automatically imported or not to be imported.

    %aimport foo

    • Import module ‘foo’ and mark it to be autoreloaded for %autoreload 1

    %aimport -foo

    • Mark module ‘foo’ to not be autoreloaded.

    This generally works good for my use, but there are some cavetas:

    • Replacing code objects does not always succeed: changing a @property in a class to an ordinary method or a method to a member variable can cause problems (but in old objects only).
    • Functions that are removed (eg. via monkey-patching) from a module before it is reloaded are not upgraded.
    • C extension modules cannot be reloaded, and so cannot be autoreloaded.
    0 讨论(0)
  • 2020-12-22 19:18

    Not exactly what you want, but I now tend to build myself management commands for testing and fiddling with things.

    In the command you can set up a bunch of locals the way you want and afterwards drop into an interactive shell.

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

    No reload, but an easy and less annoying way to interactively test django functionality.

    0 讨论(0)
提交回复
热议问题