2014-01-20 10:45:21 +08:00
# -*- coding: utf-8 -*-
2014-01-26 06:22:03 +08:00
2014-01-20 10:45:21 +08:00
from __future__ import unicode_literals
2008-09-22 14:03:24 +08:00
"""
Base classes for writing management commands ( named commands which can
be executed through ` ` django - admin . py ` ` or ` ` manage . py ` ` ) .
"""
2013-10-15 02:24:57 +08:00
2007-10-14 00:02:54 +08:00
import os
import sys
2013-12-25 06:43:47 +08:00
import warnings
2011-12-23 06:38:02 +08:00
2013-10-16 22:24:59 +08:00
from argparse import ArgumentParser
from optparse import OptionParser
2007-10-14 00:02:54 +08:00
2007-09-10 05:57:59 +08:00
import django
2014-01-20 10:45:21 +08:00
from django . core import checks
from django . core . exceptions import ImproperlyConfigured
2013-02-23 23:28:45 +08:00
from django . core . management . color import color_style , no_style
2013-10-16 22:24:59 +08:00
from django . utils . deprecation import RemovedInDjango19Warning , RemovedInDjango20Warning
2012-08-30 04:40:51 +08:00
from django . utils . encoding import force_str
2007-08-16 14:06:55 +08:00
2011-12-23 06:38:02 +08:00
2007-08-16 14:06:55 +08:00
class CommandError ( Exception ) :
2008-09-22 14:03:24 +08:00
"""
Exception class indicating a problem while executing a management
command .
If this exception is raised during the execution of a management
command , it will be caught and turned into a nicely - printed error
message to the appropriate output stream ( i . e . , stderr ) ; as a
result , raising this exception ( with a sensible description of the
error ) is the preferred way to indicate that something has gone
wrong in the execution of a command .
2010-03-18 21:24:11 +08:00
2008-09-22 14:03:24 +08:00
"""
2007-08-16 14:06:55 +08:00
pass
2011-12-23 06:38:02 +08:00
2013-10-16 22:24:59 +08:00
class CommandParser ( ArgumentParser ) :
"""
Customized ArgumentParser class to improve some error messages and prevent
SystemExit in several occasions , as SystemExit is unacceptable when a
command is called programmatically .
"""
def __init__ ( self , cmd , * * kwargs ) :
self . cmd = cmd
super ( CommandParser , self ) . __init__ ( * * kwargs )
def parse_args ( self , args = None , namespace = None ) :
# Catch missing argument for a better error message
if ( hasattr ( self . cmd , ' missing_args_message ' ) and
not ( args or any ( [ not arg . startswith ( ' - ' ) for arg in args ] ) ) ) :
2014-06-15 00:12:43 +08:00
self . error ( self . cmd . missing_args_message )
2013-10-16 22:24:59 +08:00
return super ( CommandParser , self ) . parse_args ( args , namespace )
def error ( self , message ) :
2014-06-15 00:12:43 +08:00
if self . cmd . _called_from_command_line :
super ( CommandParser , self ) . error ( message )
else :
raise CommandError ( " Error: %s " % message )
2013-10-16 22:24:59 +08:00
2007-09-22 00:19:20 +08:00
def handle_default_options ( options ) :
"""
2008-09-22 14:03:24 +08:00
Include any default options that all commands should accept here
so that ManagementUtility can handle them before searching for
user commands .
2010-03-18 21:24:11 +08:00
2007-09-22 00:19:20 +08:00
"""
if options . settings :
os . environ [ ' DJANGO_SETTINGS_MODULE ' ] = options . settings
if options . pythonpath :
sys . path . insert ( 0 , options . pythonpath )
2007-10-14 00:40:20 +08:00
2011-12-23 06:38:02 +08:00
2012-05-19 19:51:54 +08:00
class OutputWrapper ( object ) :
"""
Wrapper around stdout / stderr
"""
2012-05-26 17:43:37 +08:00
def __init__ ( self , out , style_func = None , ending = ' \n ' ) :
2012-05-19 19:51:54 +08:00
self . _out = out
self . style_func = None
if hasattr ( out , ' isatty ' ) and out . isatty ( ) :
self . style_func = style_func
2012-05-26 17:43:37 +08:00
self . ending = ending
2012-05-19 19:51:54 +08:00
def __getattr__ ( self , name ) :
return getattr ( self . _out , name )
2012-05-26 17:43:37 +08:00
def write ( self , msg , style_func = None , ending = None ) :
2013-05-17 22:33:36 +08:00
ending = self . ending if ending is None else ending
2012-05-19 19:51:54 +08:00
if ending and not msg . endswith ( ending ) :
msg + = ending
2012-05-26 17:43:37 +08:00
style_func = [ f for f in ( style_func , self . style_func , lambda x : x )
if f is not None ] [ 0 ]
2012-08-30 04:40:51 +08:00
self . _out . write ( force_str ( style_func ( msg ) ) )
2012-05-19 19:51:54 +08:00
2007-08-16 14:06:55 +08:00
class BaseCommand ( object ) :
2008-09-22 14:03:24 +08:00
"""
The base class from which all management commands ultimately
derive .
Use this class if you want access to all of the mechanisms which
parse the command - line arguments and work out what code to call in
response ; if you don ' t need to change any of that behavior,
consider using one of the subclasses defined in this file .
If you are interested in overriding / customizing various aspects of
the command - parsing and - execution behavior , the normal flow works
as follows :
1. ` ` django - admin . py ` ` or ` ` manage . py ` ` loads the command class
and calls its ` ` run_from_argv ( ) ` ` method .
2. The ` ` run_from_argv ( ) ` ` method calls ` ` create_parser ( ) ` ` to get
2013-10-16 22:24:59 +08:00
an ` ` ArgumentParser ` ` for the arguments , parses them , performs
2008-09-22 14:03:24 +08:00
any environment changes requested by options like
` ` pythonpath ` ` , and then calls the ` ` execute ( ) ` ` method ,
passing the parsed arguments .
3. The ` ` execute ( ) ` ` method attempts to carry out the command by
calling the ` ` handle ( ) ` ` method with the parsed arguments ; any
output produced by ` ` handle ( ) ` ` will be printed to standard
output and , if the command is intended to produce a block of
SQL statements , will be wrapped in ` ` BEGIN ` ` and ` ` COMMIT ` ` .
2012-05-27 02:50:44 +08:00
4. If ` ` handle ( ) ` ` or ` ` execute ( ) ` ` raised any exception ( e . g .
` ` CommandError ` ` ) , ` ` run_from_argv ( ) ` ` will instead print an error
message to ` ` stderr ` ` .
2008-09-22 14:03:24 +08:00
Thus , the ` ` handle ( ) ` ` method is typically the starting point for
subclasses ; many built - in commands and command types either place
all of their logic in ` ` handle ( ) ` ` , or perform some additional
parsing work in ` ` handle ( ) ` ` and then delegate from it to more
specialized methods as needed .
Several attributes affect behavior at various steps along the way :
2010-03-18 21:24:11 +08:00
2008-09-22 14:03:24 +08:00
` ` args ` `
A string listing the arguments accepted by the command ,
suitable for use in help messages ; e . g . , a command which takes
2013-12-25 06:43:47 +08:00
a list of application names might set this to ' <app_label
app_label . . . > ' .
2008-09-22 14:03:24 +08:00
` ` can_import_settings ` `
A boolean indicating whether the command needs to be able to
import Django settings ; if ` ` True ` ` , ` ` execute ( ) ` ` will verify
that this is possible before proceeding . Default value is
` ` True ` ` .
` ` help ` `
A short description of the command , which will be printed in
help messages .
` ` option_list ` `
This is the list of ` ` optparse ` ` options which will be fed
into the command ' s ``OptionParser`` for parsing arguments.
2013-10-16 22:24:59 +08:00
Deprecated and will be removed in Django 2.0 .
2008-09-22 14:03:24 +08:00
` ` output_transaction ` `
A boolean indicating whether the command outputs SQL
statements ; if ` ` True ` ` , the output will automatically be
wrapped with ` ` BEGIN ; ` ` and ` ` COMMIT ; ` ` . Default value is
` ` False ` ` .
2014-01-20 10:45:21 +08:00
` ` requires_system_checks ` `
A boolean ; if ` ` True ` ` , entire Django project will be checked for errors
prior to executing the command . Default value is ` ` True ` ` .
To validate an individual application ' s models
rather than all applications ' models, call
` ` self . check ( app_configs ) ` ` from ` ` handle ( ) ` ` , where ` ` app_configs ` `
is the list of application ' s configuration provided by the
app registry .
2008-09-22 14:03:24 +08:00
` ` requires_model_validation ` `
2014-01-20 10:45:21 +08:00
DEPRECATED - This value will only be used if requires_system_checks
has not been provided . Defining both ` ` requires_system_checks ` ` and
` ` requires_model_validation ` ` will result in an error .
2008-09-22 14:03:24 +08:00
A boolean ; if ` ` True ` ` , validation of installed models will be
performed prior to executing the command . Default value is
` ` True ` ` . To validate an individual application ' s models
rather than all applications ' models, call
2013-12-30 04:46:26 +08:00
` ` self . validate ( app_config ) ` ` from ` ` handle ( ) ` ` , where ` ` app_config ` `
is the application ' s configuration provided by the app registry.
2010-03-18 21:24:11 +08:00
2013-02-04 07:53:48 +08:00
` ` leave_locale_alone ` `
A boolean indicating whether the locale set in settings should be
preserved during the execution of the command instead of being
forcibly set to ' en-us ' .
Default value is ` ` False ` ` .
Make sure you know what you are doing if you decide to change the value
2013-02-04 19:55:45 +08:00
of this option in your custom command if it creates database content
that is locale - sensitive and such content shouldn ' t contain any
translations ( like it happens e . g . with django . contrim . auth
permissions ) as making the locale differ from the de facto default
' en-us ' might cause unintended effects .
2013-02-04 07:53:48 +08:00
This option can ' t be False when the can_import_settings option is set
to False too because attempting to set the locale needs access to
settings . This condition will generate a CommandError .
2008-09-22 14:03:24 +08:00
"""
2007-08-16 14:06:55 +08:00
# Metadata about this command.
2013-10-16 22:24:59 +08:00
option_list = ( )
2007-08-16 14:06:55 +08:00
help = ' '
args = ' '
# Configuration shortcuts that alter various logic.
2014-06-15 00:12:43 +08:00
_called_from_command_line = False
2007-08-16 14:06:55 +08:00
can_import_settings = True
2011-12-23 06:38:02 +08:00
output_transaction = False # Whether to wrap the output in a "BEGIN; COMMIT;"
2013-02-04 07:53:48 +08:00
leave_locale_alone = False
2007-08-16 14:06:55 +08:00
2014-01-20 10:45:21 +08:00
# Uncomment the following line of code after deprecation plan for
# requires_model_validation comes to completion:
#
# requires_system_checks = True
2007-08-16 14:06:55 +08:00
def __init__ ( self ) :
self . style = color_style ( )
2014-03-02 22:25:53 +08:00
# `requires_model_validation` is deprecated in favor of
2014-01-20 10:45:21 +08:00
# `requires_system_checks`. If both options are present, an error is
# raised. Otherwise the present option is used. If none of them is
# defined, the default value (True) is used.
has_old_option = hasattr ( self , ' requires_model_validation ' )
has_new_option = hasattr ( self , ' requires_system_checks ' )
if has_old_option :
warnings . warn (
' " requires_model_validation " is deprecated '
2014-03-02 22:25:53 +08:00
' in favor of " requires_system_checks " . ' ,
2014-02-27 05:48:20 +08:00
RemovedInDjango19Warning )
2014-01-20 10:45:21 +08:00
if has_old_option and has_new_option :
raise ImproperlyConfigured (
' Command %s defines both " requires_model_validation " '
' and " requires_system_checks " , which is illegal. Use only '
' " requires_system_checks " . ' % self . __class__ . __name__ )
self . requires_system_checks = (
self . requires_system_checks if has_new_option else
self . requires_model_validation if has_old_option else
True )
2013-10-16 22:24:59 +08:00
@property
def use_argparse ( self ) :
return not bool ( self . option_list )
2007-09-10 05:57:59 +08:00
def get_version ( self ) :
"""
2008-09-22 14:03:24 +08:00
Return the Django version , which should be correct for all
built - in Django commands . User - supplied commands should
override this method .
2010-03-18 21:24:11 +08:00
2007-09-10 05:57:59 +08:00
"""
return django . get_version ( )
2007-09-11 12:24:35 +08:00
def usage ( self , subcommand ) :
2008-09-22 14:03:24 +08:00
"""
Return a brief description of how to use this command , by
default from the attribute ` ` self . help ` ` .
2010-03-18 21:24:11 +08:00
2008-09-22 14:03:24 +08:00
"""
2007-09-11 12:24:35 +08:00
usage = ' %% prog %s [options] %s ' % ( subcommand , self . args )
2007-09-10 05:57:59 +08:00
if self . help :
return ' %s \n \n %s ' % ( usage , self . help )
else :
return usage
2007-09-11 12:24:35 +08:00
def create_parser ( self , prog_name , subcommand ) :
2008-09-22 14:03:24 +08:00
"""
2013-10-16 22:24:59 +08:00
Create and return the ` ` ArgumentParser ` ` which will be used to
2008-09-22 14:03:24 +08:00
parse the arguments to this command .
2010-03-18 21:24:11 +08:00
2008-09-22 14:03:24 +08:00
"""
2013-10-16 22:24:59 +08:00
if not self . use_argparse :
# Backwards compatibility: use deprecated optparse module
warnings . warn ( " OptionParser usage for Django management commands "
" is deprecated, use ArgumentParser instead " ,
RemovedInDjango20Warning )
parser = OptionParser ( prog = prog_name ,
usage = self . usage ( subcommand ) ,
version = self . get_version ( ) )
parser . add_option ( ' -v ' , ' --verbosity ' , action = ' store ' , dest = ' verbosity ' , default = ' 1 ' ,
type = ' choice ' , choices = [ ' 0 ' , ' 1 ' , ' 2 ' , ' 3 ' ] ,
help = ' Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output ' )
parser . add_option ( ' --settings ' ,
help = ' The Python path to a settings module, e.g. " myproject.settings.main " . If this isn \' t provided, the DJANGO_SETTINGS_MODULE environment variable will be used. ' )
parser . add_option ( ' --pythonpath ' ,
help = ' A directory to add to the Python path, e.g. " /home/djangoprojects/myproject " . ' ) ,
parser . add_option ( ' --traceback ' , action = ' store_true ' ,
help = ' Raise on exception ' )
parser . add_option ( ' --no-color ' , action = ' store_true ' , dest = ' no_color ' , default = False ,
help = " Don ' t colorize the command output. " )
for opt in self . option_list :
parser . add_option ( opt )
else :
2014-06-15 02:01:02 +08:00
parser = CommandParser ( self , prog = " %s %s " % ( os . path . basename ( prog_name ) , subcommand ) ,
description = self . help or None )
2013-10-16 22:24:59 +08:00
parser . add_argument ( ' --version ' , action = ' version ' , version = self . get_version ( ) )
parser . add_argument ( ' -v ' , ' --verbosity ' , action = ' store ' , dest = ' verbosity ' , default = ' 1 ' ,
type = int , choices = [ 0 , 1 , 2 , 3 ] ,
help = ' Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output ' )
parser . add_argument ( ' --settings ' ,
help = ' The Python path to a settings module, e.g. " myproject.settings.main " . If this isn \' t provided, the DJANGO_SETTINGS_MODULE environment variable will be used. ' )
parser . add_argument ( ' --pythonpath ' ,
help = ' A directory to add to the Python path, e.g. " /home/djangoprojects/myproject " . ' )
parser . add_argument ( ' --traceback ' , action = ' store_true ' ,
help = ' Raise on exception ' )
parser . add_argument ( ' --no-color ' , action = ' store_true ' , dest = ' no_color ' , default = False ,
help = " Don ' t colorize the command output. " )
if self . args :
# Keep compatibility and always accept positional arguments, like optparse when args is set
parser . add_argument ( ' args ' , nargs = ' * ' )
self . add_arguments ( parser )
return parser
def add_arguments ( self , parser ) :
"""
Entry point for subclassed commands to add custom arguments .
"""
pass
2007-09-10 05:57:59 +08:00
2007-09-11 12:24:35 +08:00
def print_help ( self , prog_name , subcommand ) :
2008-09-22 14:03:24 +08:00
"""
Print the help message for this command , derived from
` ` self . usage ( ) ` ` .
2010-03-18 21:24:11 +08:00
2008-09-22 14:03:24 +08:00
"""
2007-09-11 12:24:35 +08:00
parser = self . create_parser ( prog_name , subcommand )
2007-09-10 05:57:59 +08:00
parser . print_help ( )
2007-09-11 11:46:35 +08:00
def run_from_argv ( self , argv ) :
2008-09-22 14:03:24 +08:00
"""
Set up any environment changes requested ( e . g . , Python path
2012-05-27 02:50:44 +08:00
and Django settings ) , then run this command . If the
command raises a ` ` CommandError ` ` , intercept it and print it sensibly
2013-05-19 00:04:45 +08:00
to stderr . If the ` ` - - traceback ` ` option is present or the raised
` ` Exception ` ` is not ` ` CommandError ` ` , raise it .
2008-09-22 14:03:24 +08:00
"""
2014-06-15 00:12:43 +08:00
self . _called_from_command_line = True
2007-09-11 12:24:35 +08:00
parser = self . create_parser ( argv [ 0 ] , argv [ 1 ] )
2013-10-16 22:24:59 +08:00
if self . use_argparse :
options = parser . parse_args ( argv [ 2 : ] )
cmd_options = vars ( options )
# Move positional args out of options to mimic legacy optparse
if ' args ' in options :
args = options . args
del cmd_options [ ' args ' ]
else :
args = ( )
else :
options , args = parser . parse_args ( argv [ 2 : ] )
cmd_options = vars ( options )
2007-09-22 00:19:20 +08:00
handle_default_options ( options )
2012-05-27 02:50:44 +08:00
try :
2013-10-16 22:24:59 +08:00
self . execute ( * args , * * cmd_options )
2012-05-27 02:50:44 +08:00
except Exception as e :
2013-05-19 00:04:45 +08:00
if options . traceback or not isinstance ( e , CommandError ) :
raise
2013-01-25 21:52:24 +08:00
# self.stderr is not guaranteed to be set here
stderr = getattr ( self , ' stderr ' , OutputWrapper ( sys . stderr , self . style . ERROR ) )
2013-05-19 00:04:45 +08:00
stderr . write ( ' %s : %s ' % ( e . __class__ . __name__ , e ) )
2012-05-27 02:50:44 +08:00
sys . exit ( 1 )
2007-09-10 05:57:59 +08:00
2007-08-16 14:06:55 +08:00
def execute ( self , * args , * * options ) :
2008-09-22 14:03:24 +08:00
"""
2014-01-20 10:45:21 +08:00
Try to execute this command , performing system checks if needed ( as
controlled by attributes ` ` self . requires_system_checks ` ` and
2012-05-27 02:50:44 +08:00
` ` self . requires_model_validation ` ` , except if force - skipped ) .
2008-09-22 14:03:24 +08:00
"""
2012-05-19 19:51:54 +08:00
self . stdout = OutputWrapper ( options . get ( ' stdout ' , sys . stdout ) )
2013-02-23 23:28:45 +08:00
if options . get ( ' no_color ' ) :
self . style = no_style ( )
self . stderr = OutputWrapper ( options . get ( ' stderr ' , sys . stderr ) )
else :
self . stderr = OutputWrapper ( options . get ( ' stderr ' , sys . stderr ) , self . style . ERROR )
2012-05-19 19:51:54 +08:00
2007-08-16 14:06:55 +08:00
if self . can_import_settings :
2013-10-18 19:25:30 +08:00
from django . conf import settings # NOQA
2013-02-04 07:53:48 +08:00
saved_locale = None
if not self . leave_locale_alone :
# Only mess with locales if we can assume we have a working
# settings file, because django.utils.translation requires settings
# (The final saying about whether the i18n machinery is active will be
# found in the value of the USE_I18N setting)
if not self . can_import_settings :
raise CommandError ( " Incompatible values of ' leave_locale_alone ' "
" ( %s ) and ' can_import_settings ' ( %s ) command "
" options. " % ( self . leave_locale_alone ,
self . can_import_settings ) )
# Switch to US English, because django-admin.py creates database
# content like permissions, and those shouldn't contain any
# translations.
2012-05-27 02:50:44 +08:00
from django . utils import translation
2013-02-04 07:53:48 +08:00
saved_locale = translation . get_language ( )
2012-05-27 02:50:44 +08:00
translation . activate ( ' en-us ' )
2011-12-11 18:03:09 +08:00
2007-08-16 14:06:55 +08:00
try :
2014-01-20 10:45:21 +08:00
if ( self . requires_system_checks and
2014-05-29 08:39:14 +08:00
not options . get ( ' skip_validation ' ) and # This will be removed at the end of deprecation process for `skip_validation`.
2014-01-20 10:45:21 +08:00
not options . get ( ' skip_checks ' ) ) :
self . check ( )
2007-08-16 14:06:55 +08:00
output = self . handle ( * args , * * options )
if output :
if self . output_transaction :
2010-05-28 21:46:12 +08:00
# This needs to be imported here, because it relies on
# settings.
from django . db import connections , DEFAULT_DB_ALIAS
connection = connections [ options . get ( ' database ' , DEFAULT_DB_ALIAS ) ]
2007-08-20 08:24:03 +08:00
if connection . ops . start_transaction_sql ( ) :
2012-05-19 19:51:54 +08:00
self . stdout . write ( self . style . SQL_KEYWORD ( connection . ops . start_transaction_sql ( ) ) )
2010-06-05 13:26:04 +08:00
self . stdout . write ( output )
2007-08-16 14:06:55 +08:00
if self . output_transaction :
2014-01-24 07:04:47 +08:00
self . stdout . write ( ' \n ' + self . style . SQL_KEYWORD ( connection . ops . end_transaction_sql ( ) ) )
2012-03-30 00:33:48 +08:00
finally :
2013-02-04 07:53:48 +08:00
if saved_locale is not None :
translation . activate ( saved_locale )
2007-08-16 14:06:55 +08:00
2013-12-30 04:46:26 +08:00
def validate ( self , app_config = None , display_num_errors = False ) :
2014-01-20 10:45:21 +08:00
""" Deprecated. Delegates to ``check``. """
if app_config is None :
app_configs = None
else :
app_configs = [ app_config ]
2010-03-18 21:24:11 +08:00
2014-01-20 10:45:21 +08:00
return self . check ( app_configs = app_configs , display_num_errors = display_num_errors )
2010-03-18 21:24:11 +08:00
2014-01-20 10:45:21 +08:00
def check ( self , app_configs = None , tags = None , display_num_errors = False ) :
2007-08-16 14:06:55 +08:00
"""
2014-01-20 10:45:21 +08:00
Uses the system check framework to validate entire Django project .
Raises CommandError for any serious message ( error or critical errors ) .
If there are only light messages ( like warnings ) , they are printed to
stderr and no exception is raised .
"""
all_issues = checks . run_checks ( app_configs = app_configs , tags = tags )
msg = " "
2014-01-23 03:09:02 +08:00
visible_issue_count = 0 # excludes silenced warnings
2014-01-20 10:45:21 +08:00
if all_issues :
debugs = [ e for e in all_issues if e . level < checks . INFO and not e . is_silenced ( ) ]
infos = [ e for e in all_issues if checks . INFO < = e . level < checks . WARNING and not e . is_silenced ( ) ]
warnings = [ e for e in all_issues if checks . WARNING < = e . level < checks . ERROR and not e . is_silenced ( ) ]
errors = [ e for e in all_issues if checks . ERROR < = e . level < checks . CRITICAL ]
criticals = [ e for e in all_issues if checks . CRITICAL < = e . level ]
sorted_issues = [
( criticals , ' CRITICALS ' ) ,
( errors , ' ERRORS ' ) ,
( warnings , ' WARNINGS ' ) ,
( infos , ' INFOS ' ) ,
( debugs , ' DEBUGS ' ) ,
]
for issues , group_name in sorted_issues :
if issues :
2014-01-23 03:09:02 +08:00
visible_issue_count + = len ( issues )
2014-01-20 10:45:21 +08:00
formatted = (
color_style ( ) . ERROR ( force_str ( e ) )
if e . is_serious ( )
else color_style ( ) . WARNING ( force_str ( e ) )
for e in issues )
formatted = " \n " . join ( sorted ( formatted ) )
msg + = ' \n %s : \n %s \n ' % ( group_name , formatted )
2014-01-23 03:09:02 +08:00
if msg :
msg = " System check identified some issues: \n %s " % msg
2014-01-20 10:45:21 +08:00
2007-08-27 08:30:37 +08:00
if display_num_errors :
2014-01-20 10:45:21 +08:00
if msg :
msg + = ' \n '
2014-01-23 03:09:02 +08:00
msg + = " System check identified %s ( %s silenced). " % (
" no issues " if visible_issue_count == 0 else
" 1 issue " if visible_issue_count == 1 else
" %s issues " % visible_issue_count ,
len ( all_issues ) - visible_issue_count ,
2014-01-20 10:45:21 +08:00
)
if any ( e . is_serious ( ) and not e . is_silenced ( ) for e in all_issues ) :
raise CommandError ( msg )
2014-01-23 03:09:02 +08:00
elif msg and visible_issue_count :
2014-01-20 10:45:21 +08:00
self . stderr . write ( msg )
elif msg :
self . stdout . write ( msg )
2007-08-16 14:06:55 +08:00
def handle ( self , * args , * * options ) :
2008-09-22 14:03:24 +08:00
"""
The actual logic of the command . Subclasses must implement
this method .
2010-03-18 21:24:11 +08:00
2008-09-22 14:03:24 +08:00
"""
2013-09-07 02:24:52 +08:00
raise NotImplementedError ( ' subclasses of BaseCommand must provide a handle() method ' )
2007-08-16 14:06:55 +08:00
2011-12-23 06:38:02 +08:00
2007-08-16 14:06:55 +08:00
class AppCommand ( BaseCommand ) :
2008-09-22 14:03:24 +08:00
"""
2013-12-25 06:43:47 +08:00
A management command which takes one or more installed application labels
as arguments , and does something with each of them .
2008-09-22 14:03:24 +08:00
Rather than implementing ` ` handle ( ) ` ` , subclasses must implement
2013-12-25 06:43:47 +08:00
` ` handle_app_config ( ) ` ` , which will be called once for each application .
2008-09-22 14:03:24 +08:00
"""
2013-10-16 22:24:59 +08:00
missing_args_message = " Enter at least one application label. "
def add_arguments ( self , parser ) :
parser . add_argument ( ' args ' , metavar = ' app_label ' , nargs = ' + ' ,
help = ' One or more application label. ' )
2007-08-16 14:06:55 +08:00
def handle ( self , * app_labels , * * options ) :
2013-12-24 19:25:17 +08:00
from django . apps import apps
2007-08-16 14:06:55 +08:00
try :
2013-12-24 19:25:17 +08:00
app_configs = [ apps . get_app_config ( app_label ) for app_label in app_labels ]
2013-12-14 18:11:52 +08:00
except ( LookupError , ImportError ) as e :
2007-08-16 14:06:55 +08:00
raise CommandError ( " %s . Are you sure your INSTALLED_APPS setting is correct? " % e )
output = [ ]
2013-12-15 01:51:58 +08:00
for app_config in app_configs :
2013-12-25 06:43:47 +08:00
app_output = self . handle_app_config ( app_config , * * options )
2007-08-16 14:06:55 +08:00
if app_output :
output . append ( app_output )
return ' \n ' . join ( output )
2013-12-25 06:43:47 +08:00
def handle_app_config ( self , app_config , * * options ) :
2008-09-22 14:03:24 +08:00
"""
2013-12-25 06:43:47 +08:00
Perform the command ' s actions for app_config, an AppConfig instance
corresponding to an application label given on the command line .
2008-09-22 14:03:24 +08:00
"""
2013-12-25 06:43:47 +08:00
try :
# During the deprecation path, keep delegating to handle_app if
# handle_app_config isn't implemented in a subclass.
handle_app = self . handle_app
except AttributeError :
# Keep only this exception when the deprecation completes.
raise NotImplementedError (
" Subclasses of AppCommand must provide "
" a handle_app_config() method. " )
else :
warnings . warn (
" AppCommand.handle_app() is superseded by "
" AppCommand.handle_app_config(). " ,
2014-02-27 05:48:20 +08:00
RemovedInDjango19Warning , stacklevel = 2 )
2013-12-25 06:43:47 +08:00
if app_config . models_module is None :
raise CommandError (
" AppCommand cannot handle app ' %s ' in legacy mode "
" because it doesn ' t have a models module. "
% app_config . label )
return handle_app ( app_config . models_module , * * options )
2007-08-16 14:06:55 +08:00
2011-12-23 06:38:02 +08:00
2007-08-16 22:34:01 +08:00
class LabelCommand ( BaseCommand ) :
2008-09-22 14:03:24 +08:00
"""
A management command which takes one or more arbitrary arguments
( labels ) on the command line , and does something with each of
them .
Rather than implementing ` ` handle ( ) ` ` , subclasses must implement
` ` handle_label ( ) ` ` , which will be called once for each label .
If the arguments should be names of installed applications , use
` ` AppCommand ` ` instead .
2010-03-18 21:24:11 +08:00
2008-09-22 14:03:24 +08:00
"""
2007-08-16 22:34:01 +08:00
label = ' label '
2013-10-16 22:24:59 +08:00
missing_args_message = " Enter at least one %s . " % label
2007-08-17 03:14:09 +08:00
2013-10-16 22:24:59 +08:00
def add_arguments ( self , parser ) :
parser . add_argument ( ' args ' , metavar = self . label , nargs = ' + ' )
2007-08-16 22:34:01 +08:00
2013-10-16 22:24:59 +08:00
def handle ( self , * labels , * * options ) :
2007-08-16 22:34:01 +08:00
output = [ ]
for label in labels :
label_output = self . handle_label ( label , * * options )
if label_output :
output . append ( label_output )
return ' \n ' . join ( output )
def handle_label ( self , label , * * options ) :
2008-09-22 14:03:24 +08:00
"""
Perform the command ' s actions for ``label``, which will be the
string as given on the command line .
2010-03-18 21:24:11 +08:00
2008-09-22 14:03:24 +08:00
"""
2013-09-07 02:24:52 +08:00
raise NotImplementedError ( ' subclasses of LabelCommand must provide a handle_label() method ' )
2007-08-16 22:34:01 +08:00
2011-12-23 06:38:02 +08:00
2007-08-16 22:34:01 +08:00
class NoArgsCommand ( BaseCommand ) :
2008-09-22 14:03:24 +08:00
"""
A command which takes no arguments on the command line .
Rather than implementing ` ` handle ( ) ` ` , subclasses must implement
` ` handle_noargs ( ) ` ` ; ` ` handle ( ) ` ` itself is overridden to ensure
no arguments are passed to the command .
Attempting to pass arguments will raise ` ` CommandError ` ` .
2010-03-18 21:24:11 +08:00
2008-09-22 14:03:24 +08:00
"""
2007-08-16 22:34:01 +08:00
args = ' '
2014-06-18 07:07:54 +08:00
def __init__ ( self ) :
warnings . warn (
" NoArgsCommand class is deprecated and will be removed in Django 2.0. "
" Use BaseCommand instead, which takes no arguments by default. " ,
RemovedInDjango20Warning
)
super ( NoArgsCommand , self ) . __init__ ( )
2007-08-16 22:34:01 +08:00
def handle ( self , * args , * * options ) :
2007-10-14 02:45:49 +08:00
if args :
2007-08-16 22:34:01 +08:00
raise CommandError ( " Command doesn ' t accept any arguments " )
return self . handle_noargs ( * * options )
def handle_noargs ( self , * * options ) :
2008-09-22 14:03:24 +08:00
"""
Perform this command ' s actions.
2010-03-18 21:24:11 +08:00
2008-09-22 14:03:24 +08:00
"""
2013-09-07 02:24:52 +08:00
raise NotImplementedError ( ' subclasses of NoArgsCommand must provide a handle_noargs() method ' )