-
-
Save Quotation/909f87320b03b028d23c to your computer and use it in GitHub Desktop.
| from django.core.management.commands.shell import Command as ShellCommand | |
| import os | |
| class Command(ShellCommand): | |
| shells = ShellCommand.shells.append('ptpython') | |
| def ptpython(self): | |
| try: | |
| # old ptpython | |
| from prompt_toolkit.contrib.repl import embed | |
| except ImportError: | |
| # new ptpython | |
| from ptpython.repl import embed | |
| history_filename = os.path.expanduser('~/.ptpython_history') | |
| embed(globals(), locals(), vi_mode=False, history_filename=history_filename) |
Thanks for sharing. For me to get it to work it I had put __init__.py in the management and comands directory. Also my function looked like this:
def ptpython(self):
from ptpython.repl import embed
embed(globals(), locals(), vi_mode=False)Updated the code to be compatible with both old and new version of ptpython. Thanks @pebreo.
Thanks for the code. One improvement: If you add configure=run_config to the embed call, it enables the standard ~/.ptpython/config.py file.
(also change import to from ptpython.repl import embed, run_config)
I looked in the Command source (my Django version is 2.2),
it defines a handy class attr shells = ['ipython', 'bpython', 'python']
which contains the list of methods similar to the ptpython method
provided by the above authors, when you run ./manage.py shell
django tries these methods in the order they are listed in this shell attr
if the method fails with ImportError (i.e. there is no installed ptpython)
it tries the next and eventually falls back to simple python as you can see
in the shells list.
So following this Django builtin logic you can do the following:
# <any app>/management/commands/shell.py
def ptpython(self, options):
...
Command.ptpython = ptpython
Command.shells.insert(0, 'ptpython')
Then the command ./manage.py shell will start Django shell with ptpython
if the ptpython is installed.
These commands will still work too:
./manage.py shell -i ptpython
./manage.py shell -i ipython
./manage.py shell -i python
First of all thanks for the code, I've been using this for a long period of time. ptpython provides very convenient way of interactions with django apis. But unfortunately this does not work anymore, at least with Django version 2.2.6
For me ./manage.py shell -i ptpython command produces following traceback:
Traceback (most recent call last):
...
File "C:\Users\yatmanov\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
utility.execute()
File "C:\Users\yatmanov\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Users\yatmanov\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\base.py", line 323, in run_from_argv
self.execute(*args, **cmd_options)
File "C:\Users\yatmanov\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\base.py", line 364, in execute
output = self.handle(*args, **options)
File "C:\Users\yatmanov\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\commands\shell.py", line 99, in handle
return getattr(self, shell)(options)
TypeError: ptpython() takes 1 positional argument but 2 were given
So I searched for other solutions and found it on ptpython project's github page: https://github.com/prompt-toolkit/ptpython#django-support
All you need to do is install django-extensions alongside with ptpython, and add it to INSTALLED_APPS. After that you can prompt ptpython by next command:
python manage.py shell_plus
If you get:
TypeError: ptpython() takes 1 positional argument but 2 were given
try changing
def ptpython(self):
to
def ptpython(self, options):
Here's my full management/commands/shell.py file:
import os
from django.core.management.commands.shell import Command
from ptpython.repl import embed
def ptpython(self, options):
history_filename = os.path.expanduser("~/.ptpython_history")
embed(globals(), locals(), vi_mode=False, history_filename=history_filename)
Command.ptpython = ptpython
Command.shells.insert(0, "ptpython")
Append is incorrect should be ShellCommand.shells + ['ptpython']
Full version:
from django.core.management.commands.shell import Command as ShellCommand
import os
class Command(ShellCommand):
shells = ShellCommand.shells + ['ptpython']
def ptpython(self, options):
from ptpython.repl import embed
history_filename = os.path.expanduser('~/.ptpython_history')
embed(globals(), locals(), vi_mode=False, history_filename=history_filename)
Put shell.py into
<any app>/management/commands/. Run