Вопрос

Almost every time I use the manage.py shell in Django, I want to have certain things imported. I want to import * from my models.py module, for instance. Currently, my work around is to put all the imports in a file named s.py, and then after I fire up the shell I type execfile('s.py').

How can I customize manage.py so that it will do the imports automatically when I start the shell? I am using Django 1.4. Thank you.

Edit: I am adding more details to make my question more clear.

Here is what I originally did:

bash> python manage.py shell
>>> from mysite.app.models import *
>>> from mysite.app2.models import *
>>> import decimal
>>> D = decimal.Decimal
# Now I am ready to work in this shell.

Typing 4 lines of boilerplate every time I start the shell is annoying. So I put those 4 lines in a file s.py. Now I do this:

bash> python manage.py shell
>>> execfile('s.py')
# Now I am ready to work.

I want to get rid of the execfile('s.py') too. I want to make manage.py do those imports automatically when I start the shell.

Нет правильного решения

Другие советы

The shell sub-command simply invokes an interactive Python interpreter, so pointing the PYTHONSTARTUP UNIX environment variable to a file containing your desired imports would work. Here is the sequence:

user@linux$ export PYTHONSTARTUP='/path/to/my/django/pythonStartup.py'; python ./manage.py shell

Where pythonStartup.py is arbitrarily named and you can name it anything you like, including s.py (although that is probably not the best name for it). =:)

You can also create the following convenience alias for that in your personal .bash_profile:

alias django-shell="export PYTHONSTARTUP='/path/to/my/django/pythonStartup.py'; python ./manage.py shell"

and then simply use that:

user@linux$ . ${HOME}/.bash_profile  # Normally you don't need to do this step.
user@linux$ django-shell

Now, you need only to edit the pythonStartup.py file to incorporate any changes to import behavior you might desire, and simply run the alias (... no need to edit or re-source your .bash_profile).

Here is what happens when I run python3 ./manage.py shell with the PYTHONSTARTUP environment variable properly pointed to the file I want imports to come from:

user@linux$ python3 ./manage.py shell
Python 3.5.1 |Anaconda custom (64-bit)| (default, Dec  7 2015, 11:16:01) 
Type "copyright", "credits" or "license" for more information.

IPython 4.2.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

Importing base set of modules often used ...

import sys, os, random, pprint, operator
import time, math
import numpy, numpy as np
import numpy.linalg
import scipy, scipy as spimport scipy.optimize
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.pylab as pylab
import pandas as pd
import sklearn.datasets
import sklearn.feature_extraction
import sklearn.linear_model
import sklearn.neighbors
import sklearn.cluster
import sklearn.preprocessing
import sklearn.decomposition
import gensim.models.word2vec

In [1]:

EDIT:

An additional tip that I forgot to mention.

If you place pythonStartup.py in the root directory of your Django projects, then creating the alias as follows:

alias django-shell="export PYTHONSTARTUP='./pythonStartup.py'; python ./manage.py shell"

allows you to cd to the root directory of whatever Django project you're currently working on, and the alias will invoke that particular project's pythonStartup.py. This approach adds flexibility.

Check django-extensions, it provides a shell_plus management command that automatically imports all models for installed applications:

user@host:~/git/project (devel)$ ./manage.py shell_plus
# Shell Plus Model Imports
from django.contrib.admin.models import LogEntry
from django.contrib.auth.models import Group, Permission, User
from django.contrib.contenttypes.models import ContentType
from django.contrib.sessions.models import Session
from custom_app1.models import MyModel1
from custom_app2.models import MyModel2
from custom_app3.models import MyModel3
# Shell Plus Django Imports
from django.utils import timezone
from django.conf import settings
from django.core.cache import cache
from django.db.models import Avg, Count, F, Max, Min, Sum, Q, Prefetch, Case, When
from django.core.urlresolvers import reverse
from django.db import transaction
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)

Note that custom app models are also imported.

I think you should not override the default shell or manage.py commands because you are going lo use them at other places . If you have a local settings file you might want to add them to your local settings file, But you could end up with circular imports if you are not careful . Also you should write your own extension to shell

Check this:

https://github.com/django-extensions/django-extensions/blob/master/django_extensions/management/shells.py

There is a django extension for you, its shell_plus.

1. pip install django-extensions

2. add 'django-extensions' to your settings.py's INSTALLED_APPS[]

3. RUN COMMAND >>>>> python manage.py shell_plus

It's not hard to create a new shell command that subclasses and shadows the original one and run arbitrary code.

I'm certain this must be a bad idea... but it's easy! And I use it!

Here's an example:

from django.core.management.commands.shell import Command as ShellCommand


class Command(ShellCommand):
    def ipython(self, options):
        print("REMINDER - THIS IS JOHN'S HACKED SHELL")
        from IPython import start_ipython

        script_to_run_on_startup = """
        from django.conf import settings
        from my_app.models import MyModel


        expected_variables = ['In','Out','get_ipython','exit','quit', 'expected_variables']
        available_variables = [k for k in locals().keys() if k[0] != '_' and k not in expected_variables]

        print(f'\\navailable_variables:\\n{available_variables}')
        """

        argv = ['-c', script_to_run_on_startup, '-i']

        start_ipython(argv)

Now stick this in a command file named shell.py.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top