web/lib/django_extensions/management/commands/shell_plus.py
changeset 3 526ebd3988b0
equal deleted inserted replaced
1:ebaad720f88b 3:526ebd3988b0
       
     1 import os
       
     2 from django.core.management.base import NoArgsCommand
       
     3 from optparse import make_option
       
     4 
       
     5 class Command(NoArgsCommand):
       
     6     option_list = NoArgsCommand.option_list + (
       
     7         make_option('--plain', action='store_true', dest='plain',
       
     8             help='Tells Django to use plain Python, not IPython.'),
       
     9         make_option('--no-pythonrc', action='store_true', dest='no_pythonrc',
       
    10             help='Tells Django to use plain Python, not IPython.'),
       
    11     )
       
    12     help = "Like the 'shell' command but autoloads the models of all installed Django apps."
       
    13 
       
    14     requires_model_validation = True
       
    15 
       
    16     def handle_noargs(self, **options):
       
    17         # XXX: (Temporary) workaround for ticket #1796: force early loading of all
       
    18         # models from installed apps. (this is fixed by now, but leaving it here
       
    19         # for people using 0.96 or older trunk (pre [5919]) versions.
       
    20         from django.db.models.loading import get_models, get_apps
       
    21         loaded_models = get_models()
       
    22 
       
    23         use_plain = options.get('plain', False)
       
    24         use_pythonrc = not options.get('no_pythonrc', True)
       
    25 
       
    26         # Set up a dictionary to serve as the environment for the shell, so
       
    27         # that tab completion works on objects that are imported at runtime.
       
    28         # See ticket 5082.
       
    29         from django.conf import settings
       
    30         imported_objects = {'settings': settings}
       
    31         for app_mod in get_apps():
       
    32             app_models = get_models(app_mod)
       
    33             if not app_models:
       
    34                 continue
       
    35             model_labels = ", ".join([model.__name__ for model in app_models])
       
    36             print self.style.SQL_COLTYPE("From '%s' autoload: %s" % (app_mod.__name__.split('.')[-2], model_labels))
       
    37             for model in app_models:
       
    38                 try:
       
    39                     imported_objects[model.__name__] = getattr(__import__(app_mod.__name__, {}, {}, model.__name__), model.__name__)
       
    40                 except AttributeError, e:
       
    41                     print self.style.ERROR_OUTPUT("Failed to import '%s' from '%s' reason: %s" % (model.__name__, app_mod.__name__.split('.')[-2], str(e)))
       
    42                     continue
       
    43         try:
       
    44             if use_plain:
       
    45                 # Don't bother loading IPython, because the user wants plain Python.
       
    46                 raise ImportError
       
    47             import IPython
       
    48             # Explicitly pass an empty list as arguments, because otherwise IPython
       
    49             # would use sys.argv from this script.
       
    50             shell = IPython.Shell.IPShell(argv=[], user_ns=imported_objects)
       
    51             shell.mainloop()
       
    52         except ImportError:
       
    53             # Using normal Python shell
       
    54             import code
       
    55             try: # Try activating rlcompleter, because it's handy.
       
    56                 import readline
       
    57             except ImportError:
       
    58                 pass
       
    59             else:
       
    60                 # We don't have to wrap the following import in a 'try', because
       
    61                 # we already know 'readline' was imported successfully.
       
    62                 import rlcompleter
       
    63                 readline.set_completer(rlcompleter.Completer(imported_objects).complete)
       
    64                 readline.parse_and_bind("tab:complete")
       
    65 
       
    66             # We want to honor both $PYTHONSTARTUP and .pythonrc.py, so follow system
       
    67             # conventions and get $PYTHONSTARTUP first then import user.
       
    68             if use_pythonrc:
       
    69                 pythonrc = os.environ.get("PYTHONSTARTUP") 
       
    70                 if pythonrc and os.path.isfile(pythonrc): 
       
    71                     try: 
       
    72                         execfile(pythonrc) 
       
    73                     except NameError: 
       
    74                         pass
       
    75                 # This will import .pythonrc.py as a side-effect
       
    76                 import user
       
    77             code.interact(local=imported_objects)