Index: django/core/management/color.py
===================================================================
--- django/core/management/color.py	(revision 12937)
+++ django/core/management/color.py	(working copy)
@@ -19,20 +19,20 @@
         return False
     return True
 
-def color_style():
+def color_style(palettes=termcolors.PALETTES):
     """Returns a Style object with the Django color scheme."""
     if not supports_color():
         style = no_style()
     else:
         DJANGO_COLORS = os.environ.get('DJANGO_COLORS', '')
-        color_settings = termcolors.parse_color_setting(DJANGO_COLORS)
+        color_settings = termcolors.parse_color_setting(DJANGO_COLORS, palettes)
         if color_settings:
             class dummy: pass
             style = dummy()
             # The nocolor palette has all available roles.
             # Use that pallete as the basis for populating
             # the palette as defined in the environment.
-            for role in termcolors.PALETTES[termcolors.NOCOLOR_PALETTE]:
+            for role in palettes[termcolors.NOCOLOR_PALETTE]:
                 format = color_settings.get(role,{})
                 setattr(style, role, termcolors.make_style(**format))
             # For backwards compatibility,
Index: django/utils/termcolors.py
===================================================================
--- django/utils/termcolors.py	(revision 12937)
+++ django/utils/termcolors.py	(working copy)
@@ -50,8 +50,8 @@
         if o in opt_dict:
             code_list.append(opt_dict[o])
     if 'noreset' not in opts:
-        text = text + '\x1b[%sm' % RESET
-    return ('\x1b[%sm' % ';'.join(code_list)) + text
+        text = '%s\x1b[%sm' % (text, RESET)
+    return '\x1b[%sm%s' % (';'.join(code_list), text)
 
 def make_style(opts=(), **kwargs):
     """
@@ -71,12 +71,12 @@
 
 PALETTES = {
     NOCOLOR_PALETTE: {
-        'ERROR':        {},
-        'NOTICE':       {},
-        'SQL_FIELD':    {},
-        'SQL_COLTYPE':  {},
-        'SQL_KEYWORD':  {},
-        'SQL_TABLE':    {},
+        'ERROR':             {},
+        'NOTICE':            {},
+        'SQL_FIELD':         {},
+        'SQL_COLTYPE':       {},
+        'SQL_KEYWORD':       {},
+        'SQL_TABLE':         {},
         'HTTP_INFO':         {},
         'HTTP_SUCCESS':      {},
         'HTTP_REDIRECT':     {},
@@ -86,12 +86,12 @@
         'HTTP_SERVER_ERROR': {},
     },
     DARK_PALETTE: {
-        'ERROR':        { 'fg': 'red', 'opts': ('bold',) },
-        'NOTICE':       { 'fg': 'red' },
-        'SQL_FIELD':    { 'fg': 'green', 'opts': ('bold',) },
-        'SQL_COLTYPE':  { 'fg': 'green' },
-        'SQL_KEYWORD':  { 'fg': 'yellow' },
-        'SQL_TABLE':    { 'opts': ('bold',) },
+        'ERROR':             { 'fg': 'red', 'opts': ('bold',) },
+        'NOTICE':            { 'fg': 'red' },
+        'SQL_FIELD':         { 'fg': 'green', 'opts': ('bold',) },
+        'SQL_COLTYPE':       { 'fg': 'green' },
+        'SQL_KEYWORD':       { 'fg': 'yellow' },
+        'SQL_TABLE':         { 'opts': ('bold',) },
         'HTTP_INFO':         { 'opts': ('bold',) },
         'HTTP_SUCCESS':      { },
         'HTTP_REDIRECT':     { 'fg': 'green' },
@@ -101,12 +101,12 @@
         'HTTP_SERVER_ERROR': { 'fg': 'magenta', 'opts': ('bold',) },
     },
     LIGHT_PALETTE: {
-        'ERROR':        { 'fg': 'red', 'opts': ('bold',) },
-        'NOTICE':       { 'fg': 'red' },
-        'SQL_FIELD':    { 'fg': 'green', 'opts': ('bold',) },
-        'SQL_COLTYPE':  { 'fg': 'green' },
-        'SQL_KEYWORD':  { 'fg': 'blue' },
-        'SQL_TABLE':    { 'opts': ('bold',) },
+        'ERROR':             { 'fg': 'red', 'opts': ('bold',) },
+        'NOTICE':            { 'fg': 'red' },
+        'SQL_FIELD':         { 'fg': 'green', 'opts': ('bold',) },
+        'SQL_COLTYPE':       { 'fg': 'green' },
+        'SQL_KEYWORD':       { 'fg': 'blue' },
+        'SQL_TABLE':         { 'opts': ('bold',) },
         'HTTP_INFO':         { 'opts': ('bold',) },
         'HTTP_SUCCESS':      { },
         'HTTP_REDIRECT':     { 'fg': 'green', 'opts': ('bold',) },
@@ -118,7 +118,7 @@
 }
 DEFAULT_PALETTE = DARK_PALETTE
 
-def parse_color_setting(config_string):
+def parse_color_setting(config_string, palettes=PALETTES):
     """Parse a DJANGO_COLORS environment variable to produce the system palette
 
     The general form of a pallete definition is:
@@ -136,6 +136,9 @@
     definitions for each role. Any individual definitions following the pallete
     definition will augment the base palette definition.
 
+    An alternate dictionary of palettes may be provided to extend or override
+    Django's default palettes (e.g. with new roles or different colours).
+
     Valid roles:
         'error', 'notice', 'sql_field', 'sql_coltype', 'sql_keyword', 'sql_table',
         'http_info', 'http_success', 'http_redirect', 'http_bad_request',
Index: tests/regressiontests/utils/termcolors.py
===================================================================
--- tests/regressiontests/utils/termcolors.py	(revision 12937)
+++ tests/regressiontests/utils/termcolors.py	(working copy)
@@ -147,3 +147,17 @@
         self.assertEquals(parse_color_setting('error=green,bLiNk'),
                           dict(PALETTES[NOCOLOR_PALETTE],
                             ERROR={'fg':'green', 'opts': ('blink',)}))
+
+    def test_custom_palette(self):
+        custom_palettes = PALETTES.copy()
+        custom_palettes[NOCOLOR_PALETTE].update({'WARNING': {}, 'NOTICE': {}})
+        custom_palettes[DARK_PALETTE].update({'WARNING': {'fg': 'yellow'}, 'NOTICE': {'fg': 'cyan'}})
+        custom_palettes[LIGHT_PALETTE].update({'WARNING': {'fg': 'black', 'bg': 'yellow'}, 'NOTICE': {'fg': 'blue'}})
+        # empty string.
+        self.assertEquals(parse_color_setting('', custom_palettes), custom_palettes[DEFAULT_PALETTE])
+        # simple palette.
+        self.assertEquals(parse_color_setting('light', custom_palettes), custom_palettes[LIGHT_PALETTE])
+        # override palette.
+        self.assertEquals(parse_color_setting('light;error=green', custom_palettes),
+                          dict(custom_palettes[LIGHT_PALETTE],
+                            ERROR={'fg':'green'}))
Index: docs/ref/django-admin.txt
===================================================================
--- docs/ref/django-admin.txt	(revision 12937)
+++ docs/ref/django-admin.txt	(working copy)
@@ -1093,6 +1093,18 @@
 *except* for the colors for errors and notices which would be
 overridden as specified.
 
+If you need to define new roles or default colors for use in your own
+management commands and still want to retain the ability for users to
+customize them with the ``DJANGO_COLORS`` environment variable, you can pass
+your own dictionary of color palettes to the ``color_style()`` function::
+
+    from django.core.management.color import color_style
+    from django.utils.termcolors import PALETTES
+    PALETTES['nocolor'].update(WARNING={})
+    PALETTES['dark'].update(WARNING={'fg': 'yellow'})
+    PALETTES['light'].update(WARNING={'fg': 'black', 'bg': 'yellow'})
+    style = color_style(PALETTES)
+
 Bash completion
 ---------------
 
