Skip to main content

Development Server and Shell Utilities

The development server and interactive shell are essential tools for rapid prototyping and debugging. This guide demonstrates how to use these utilities, customize their behavior, and execute one-off scripts within the Django environment.

Starting the Development Server

To start the lightweight WSGI development server, use the runserver command. By default, it binds to 127.0.0.1:8000 and enables auto-reloading and threading.

python manage.py runserver

Binding to a Specific Address and Port

You can specify a custom address and port by passing them as a positional argument to django.core.management.commands.runserver.Command.

# Bind to all available IP addresses on port 8080
python manage.py runserver 0.0.0.0:8080

# Use an IPv6 address
python manage.py runserver -6 [::1]:8000

Disabling Auto-Reload and Threading

In some debugging scenarios, you may want to disable the auto-reloader or threading:

# Disable the auto-reloader (useful for certain debuggers)
python manage.py runserver --noreload

# Disable threading (runs the server in a single-threaded process)
python manage.py runserver --nothreading

Suppressing the Production Warning

The server displays a warning that it is not suitable for production. You can suppress this warning by setting the DJANGO_RUNSERVER_HIDE_WARNING environment variable:

export DJANGO_RUNSERVER_HIDE_WARNING=true
python manage.py runserver

Using the Interactive Shell

The shell command provides a Python interpreter pre-configured with your project's environment. It automatically imports models and common utilities to speed up data manipulation and testing.

python manage.py shell

Selecting an Interface

If you have IPython or bpython installed, Django will attempt to use them. You can force a specific interface using the -i or --interface flag:

python manage.py shell -i ipython
python manage.py shell -i bpython
python manage.py shell -i python

Automatic Imports

By default, django.core.management.commands.shell.Command imports the following into the shell's namespace:

  • settings from django.conf
  • connection and reset_queries from django.db
  • models and functions from django.db.models
  • timezone from django.utils
  • All models from your INSTALLED_APPS

To see exactly what was imported, use verbosity level 2:

python manage.py shell -v 2

If you want to start a clean shell without these imports, use the --no-imports flag:

python manage.py shell --no-imports

Executing One-off Commands and Scripts

You can execute Python code within the Django context without entering an interactive session using the -c flag or by piping code via standard input.

Using the Command Flag

This is useful for quick checks or automation tasks, as seen in tests/shell/tests.py:

from django.core.management import call_command

# Execute a snippet and exit
call_command(
"shell",
command=(
"from django.contrib.auth.models import User; "
"print(User.objects.count())"
),
)

Piping via Standard Input

On non-Windows systems, you can pipe a script directly into the shell:

echo "from django.utils import timezone; print(timezone.now())" | python manage.py shell

Customizing Server Behavior

You can extend the development server by subclassing runserver.Command. A common pattern is wrapping the WSGI handler to add middleware-like functionality, such as serving static files.

The following example from django/contrib/staticfiles/management/commands/runserver.py shows how to wrap the default handler with a StaticFilesHandler:

from django.contrib.staticfiles.handlers import StaticFilesHandler
from django.core.management.commands.runserver import Command as RunserverCommand

class Command(RunserverCommand):
def get_handler(self, *args, **options):
# Get the default WSGI handler
handler = super().get_handler(*args, **options)

use_static_handler = options.get("use_static_handler", True)
insecure_serving = options.get("insecure_serving", False)

# Wrap the handler if static file serving is enabled
if use_static_handler and (settings.DEBUG or insecure_serving):
return StaticFilesHandler(handler)
return handler

Troubleshooting

Port Already in Use

If you see Error: That port is already in use., another process is already listening on the requested port. You can either stop that process or specify a different port:

python manage.py runserver 8001

AppRegistryNotReady in Shell

If the shell fails to perform automatic imports with an AppRegistryNotReady error, ensure your DJANGO_SETTINGS_MODULE environment variable is correctly set. The shell requires a valid settings module to discover models:

export DJANGO_SETTINGS_MODULE=myproject.settings
python manage.py shell

Stdin Limitations on Windows

The shell command cannot read from standard input on Windows due to limitations in the select() system call. Use the -c flag instead for one-off commands on Windows platforms.