diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py
index f1192fe..9bb3303 100644
--- a/django/core/management/__init__.py
+++ b/django/core/management/__init__.py
@@ -261,7 +261,82 @@ class ManagementUtility(object):
                 (subcommand, self.prog_name))
             sys.exit(1)
         return klass
-
+    
+    def autocomplete(self, parser):
+        """
+        Outputs a list of bash completion suggestions
+        """
+        if os.environ.has_key('DJANGO_AUTO_COMPLETE'):
+            # map bash variables
+            cwords = os.environ['COMP_WORDS'].split()
+            cline = os.environ['COMP_LINE']
+            cpoint = int(os.environ['COMP_POINT'])
+            cword = int(os.environ['COMP_CWORD'])
+
+            # get all available subcommands & add special cases
+            completions = get_commands().keys()
+            completions += ['help',]
+
+            # subcommand options completion
+            if cword >= 2 and cwords[1] in completions:
+                # 'help' is a special case since it's not a option in 
+                # optparse and handled manually
+                if cwords[1] == 'help':
+                    sys.exit(1)
+
+                subcommand = self.fetch_command(cwords[1])
+                subcmd_options = ['--help',]
+                option_list = []
+
+                # runfcgi uses a python dict for its options. add the commands
+                # manually.
+                if cwords[1] == 'runfcgi':
+                    from django.core.servers.fastcgi import FASTCGI_OPTIONS
+                    subcmd_options = map(lambda x: x+'=', FASTCGI_OPTIONS)
+                else:
+                    option_list = subcommand.option_list
+
+                # get all options for the subcommand
+                for opt in option_list:
+                    opt_label = str(opt)
+                    # some options are specified in the short/long format
+                    # e.g. '-e/--exclude'. In this case only the long format
+                    # is included
+                    if '/' in opt_label:
+                        opt_label = opt_label.split('/')[1]
+
+                    # append equal sign for options which require arguments
+                    if opt.nargs:
+                        opt_label += '='
+                    subcmd_options.append(opt_label)
+
+                # get previously specified options
+                prev_options = cwords[2:cword]
+
+                # remove already specified options
+                for prev_option in prev_options:
+                    # check only the key, not the value
+                    if '=' in prev_option:
+                        prev_option = prev_option.split('=')[0]+'='
+
+                    if prev_option in subcmd_options:
+                        subcmd_options.remove(prev_option)
+
+                # set the remaining options as completion suggestions
+                completions = subcmd_options
+            try:
+                prefix = cwords[cword]
+            except IndexError:
+                prefix = None
+            
+            # filter completions based on prefix
+            if prefix:
+                completions = filter(lambda x: x.startswith(prefix), 
+                                     completions)
+            # output completions
+            print ' '.join(completions)
+            sys.exit(1)
+    
     def execute(self):
         """
         Given the command-line arguments, this figures out which subcommand is
@@ -273,6 +348,7 @@ class ManagementUtility(object):
         parser = LaxOptionParser(usage="%prog subcommand [options] [args]",
                                  version=get_version(),
                                  option_list=BaseCommand.option_list)
+        self.autocomplete(parser)
         try:
             options, args = parser.parse_args(self.argv)
             handle_default_options(options)
diff --git a/extras/django_bash_completion b/extras/django_bash_completion
index b805af9..940b470 100755
--- a/extras/django_bash_completion
+++ b/extras/django_bash_completion
@@ -31,136 +31,11 @@
 #
 # To uninstall, just remove the line from your .bash_profile and .bashrc.
 
-# Enable extended pattern matching operators.
-shopt -s extglob
-
 _django_completion()
 {
-    local cur prev opts actions action_shell_opts action_runfcgi_opts
-    COMPREPLY=()
-    cur="${COMP_WORDS[COMP_CWORD]}"
-    prev="${COMP_WORDS[COMP_CWORD-1]}"
-
-    # Standalone options
-    opts="--help --settings --pythonpath --noinput --noreload --format --indent --verbosity --adminmedia --version --locale --domain"
-    # Actions
-    actions="createcachetable createsuperuser compilemessages \
-             dbshell diffsettings dumpdata flush inspectdb loaddata \
-             makemessages reset runfcgi runserver shell sql sqlall sqlclear \
-             sqlcustom sqlflush sqlindexes sqlreset sqlsequencereset startapp \
-             startproject syncdb test validate"
-    # Action's options
-    action_shell_opts="--plain"
-    action_runfcgi_opts="host port socket method maxspare minspare maxchildren daemonize pidfile workdir"
-
-    if [[ # django-admin.py, django-admin, ./manage, manage.py
-          ( ${COMP_CWORD} -eq 1 &&
-            ( ${COMP_WORDS[0]} == django-admin.py ||
-              ${COMP_WORDS[0]} == django-admin ||
-              ${COMP_WORDS[0]} == ./manage.py ||
-              ${COMP_WORDS[0]} == manage.py ) )
-          ||
-          # python manage.py, /some/path/python manage.py (if manage.py exists)
-          ( ${COMP_CWORD} -eq 2 &&
-            ( $( basename -- ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) &&
-            ( $( basename -- ${COMP_WORDS[1]} ) == manage.py) &&
-            ( -r ${COMP_WORDS[1]} ) ) 
-          ||
-          ( ${COMP_CWORD} -eq 2 &&
-            ( $( basename -- ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) &&
-            ( $( basename -- ${COMP_WORDS[1]} ) == django-admin.py) &&
-            ( -r ${COMP_WORDS[1]} ) ) 
-          ||
-          ( ${COMP_CWORD} -eq 2 &&
-            ( $( basename -- ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) &&
-            ( $( basename -- ${COMP_WORDS[1]} ) == django-admin) &&
-            ( -r ${COMP_WORDS[1]} ) ) ]] ; then
-
-        case ${cur} in
-            -*)
-                COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
-                action=$COMPREPLY
-                return 0
-                ;;
-            *)
-                COMPREPLY=( $(compgen -W "${actions}" -- ${cur}) )
-                action=$COMPREPLY
-                return 0
-                ;;
-        esac
-    else
-        case ${prev} in
-            dumpdata|reset| \
-            sql|sqlall|sqlclear|sqlcustom|sqlindexes| \
-            sqlreset|sqlsequencereset|test)
-                # App completion
-                settings=""
-                # If settings.py in the PWD, use that
-                if [ -e settings.py ] ; then
-                    settings="$PWD/settings.py"
-                else
-                    # Use the ENV variable if it is set
-                    if [ $DJANGO_SETTINGS_MODULE ] ; then
-                        settings=$DJANGO_SETTINGS_MODULE
-                    fi
-                fi
-                # Couldn't find settings so return nothing
-                if [ -z $settings ] ; then
-                    COMPREPLY=()
-                # Otherwise inspect settings.py file
-                else
-                    apps=`sed -n "/INSTALLED_APPS = (/,/)/p" $settings | \
-                          grep -v "django.contrib" | 
-                          sed -n "s/^[ ]*'\(.*\.\)*\(.*\)'.*$/\2 /pg" | \
-                          tr -d "\n"`
-                    COMPREPLY=( $(compgen -W "${apps}" -- ${cur}) )
-                fi
-                return 0
-                ;;
-
-            createcachetable|cleanup|compilemessages|dbshell| \
-            diffsettings|inspectdb|makemessages| \
-            runserver|startapp|startproject|syncdb| \
-            validate)
-                COMPREPLY=()
-                return 0
-                ;;
-            shell)
-                COMPREPLY=( $(compgen -W "$action_shell_opts" -- ${cur}) )
-                return 0
-                ;;
-            runfcgi)
-                COMPREPLY=( $(compgen -W "$action_runfcgi_opts" -- ${cur}) )
-                return 0
-                ;;
-            host*|port*|socket*|method*|maxspare*|minspare*|maxchildren*|daemonize*|pidfile*|workdir*)
-                if [ "$action"  == "runfcgi" ] ; then
-                    COMPREPLY=( $(compgen -W "$action_runfcgi_opts" -- ${cur}) )
-                    return 0
-                fi
-                return 0
-                ;;
-            *)
-                #COMPREPLY=( $(compgen -W "auth core" -- ${cur}) )
-                COMPREPLY=()
-                return 0
-                ;;
-        esac
-    fi
+    COMPREPLY=( $( \
+	COMP_LINE=$COMP_LINE  COMP_POINT=$COMP_POINT \
+	COMP_WORDS="${COMP_WORDS[*]}"  COMP_CWORD=$COMP_CWORD \
+	DJANGO_AUTO_COMPLETE=1 $1 ) )
 }
-
-complete -F _django_completion django-admin.py manage.py django-admin
-
-# Support for multiple interpreters.
-unset pythons
-if command -v whereis &>/dev/null; then
-    python_interpreters=$(whereis python | cut -d " " -f 2-) 
-    for python in $python_interpreters; do
-        pythons="${pythons} $(basename -- $python)"
-    done
-    pythons=$(echo $pythons | tr " " "\n" | sort -u | tr "\n" " ")
-else
-    pythons=python    
-fi
-
-complete -F _django_completion -o default $pythons
+complete -F _django_completion django-admin.py manage.py
