call_command 参数是必需的
call_command argument is required
我正在尝试以与 this question without an answer 非常相似的方式使用 Django 的 call_command
。
我的称呼方式是:
args = []
kwargs = {
'solr_url': 'http://127.0.0.1:8983/solr/collection1',
'type': 'opinions',
'update': True,
'everything': True,
'do_commit': True,
'traceback': True,
}
call_command('cl_update_index', **kwargs)
根据 the docs,理论上应该可行。但是不行,就是不行。
这是我的命令 class 的 add_arguments
方法:
def add_arguments(self, parser):
parser.add_argument(
'--type',
type=valid_obj_type,
required=True,
help='Because the Solr indexes are loosely bound to the database, '
'commands require that the correct model is provided in this '
'argument. Current choices are "audio" or "opinions".'
)
parser.add_argument(
'--solr-url',
required=True,
type=str,
help='When swapping cores, it can be valuable to use a temporary '
'Solr URL, overriding the default value that\'s in the '
'settings, e.g., http://127.0.0.1:8983/solr/swap_core'
)
actions_group = parser.add_mutually_exclusive_group()
actions_group.add_argument(
'--update',
action='store_true',
default=False,
help='Run the command in update mode. Use this to add or update '
'items.'
)
actions_group.add_argument(
'--delete',
action='store_true',
default=False,
help='Run the command in delete mode. Use this to remove items '
'from the index. Note that this will not delete items from '
'the index that do not continue to exist in the database.'
)
parser.add_argument(
'--optimize',
action='store_true',
default=False,
help='Run the optimize command against the current index after '
'any updates or deletions are completed.'
)
parser.add_argument(
'--do-commit',
action='store_true',
default=False,
help='Performs a simple commit and nothing more.'
)
act_upon_group = parser.add_mutually_exclusive_group()
act_upon_group.add_argument(
'--everything',
action='store_true',
default=False,
help='Take action on everything in the database',
)
act_upon_group.add_argument(
'--query',
help='Take action on items fulfilling a query. Queries should be '
'formatted as Python dicts such as: "{\'court_id\':\'haw\'}"'
)
act_upon_group.add_argument(
'--items',
type=int,
nargs='*',
help='Take action on a list of items using a single '
'Celery task'
)
act_upon_group.add_argument(
'--datetime',
type=valid_date_time,
help='Take action on items newer than a date (YYYY-MM-DD) or a '
'date and time (YYYY-MM-DD HH:MM:SS)'
)
无论我在这里做什么,我都会得到:
CommandError: Error: argument --type is required
有什么想法吗?如果你真的很好奇,你可以 see the entire code here.
您用 '--type'
标志定义了一个参数,并使其成为 required
。该命令行将需要一个或多个类似于 --type avalue
.
的字符串
这看起来像 call_command
的相关部分:
def call_command(name, *args, **options):
....
parser = command.create_parser('', name)
if command.use_argparse:
# Use the `dest` option name from the parser option
opt_mapping = {sorted(s_opt.option_strings)[0].lstrip('-').replace('-', '_'): s_opt.dest
for s_opt in parser._actions if s_opt.option_strings}
arg_options = {opt_mapping.get(key, key): value for key, value in options.items()}
defaults = parser.parse_args(args=args)
defaults = dict(defaults._get_kwargs(), **arg_options)
# Move positional args out of options to mimic legacy optparse
args = defaults.pop('args', ())
它创建一个解析器,使用它自己的参数加上您添加的参数。
parser._actions if s_opt.option_strings
是带有选项标志(以 - 或 -- 开头)的参数(操作)。 opt_mapping
是标志字符串(减去前导 -s)和 'dest' 属性之间的映射。
arg_options
将您的 **kwargs
转换为可以与 parser
输出合并的内容。
defaults = parser.parse_args(args=args)
进行实际解析。也就是说,它是唯一实际使用 argparse
解析机制的代码。因此,您调用的 *args
部分模拟从交互式调用中生成 sys.argv[1:]
。
根据阅读的内容,我认为这应该可行:
args = [
'--solr-url', 'http://127.0.0.1:8983/solr/collection1',
'--type', 'opinions',
'--update'
'--everything',
'--do_commit',
'--traceback',
}
call_command('cl_update_index', *args)
而不是 **kwargs
我将值作为字符串列表传递。或者可以在 args
中传递两个 required 参数,其余的在 **kwargs
.
中传递
args = ['--solr-url', 'http://127.0.0.1:8983/solr/collection1',
'--type', 'opinions']
kwargs = {
'update': True,
'everything': True,
'do_commit': True,
'traceback': True,
}
call_command('cl_update_index', *args, **kwargs)
如果一个参数是required
,它需要通过*args
传入。 **kwargs
绕过解析器,导致它反对缺少参数。
我已经下载了最新的 django
,但还没有安装。但这里有一个 call_command
的模拟,应该测试调用选项:
import argparse
def call_command(name, *args, **options):
"""
Calls the given command, with the given options and args/kwargs.
standalone simulation of django.core.mangement call_command
"""
command = name
"""
....
"""
# Simulate argument parsing to get the option defaults (see #10080 for details).
parser = command.create_parser('', name)
if command.use_argparse:
# Use the `dest` option name from the parser option
opt_mapping = {sorted(s_opt.option_strings)[0].lstrip('-').replace('-', '_'): s_opt.dest
for s_opt in parser._actions if s_opt.option_strings}
arg_options = {opt_mapping.get(key, key): value for key, value in options.items()}
defaults = parser.parse_args(args=args)
defaults = dict(defaults._get_kwargs(), **arg_options)
# Move positional args out of options to mimic legacy optparse
args = defaults.pop('args', ())
else:
# Legacy optparse method
defaults, _ = parser.parse_args(args=[])
defaults = dict(defaults.__dict__, **options)
if 'skip_checks' not in options:
defaults['skip_checks'] = True
return command.execute(*args, **defaults)
class BaseCommand():
def __init__(self):
self.use_argparse = True
self.stdout= sys.stdout
self.stderr=sys.stderr
def execute(self, *args, **kwargs):
self.handle(*args, **kwargs)
def handle(self, *args, **kwargs):
print('args: ', args)
print('kwargs: ', kwargs)
def create_parser(self, *args, **kwargs):
parser = argparse.ArgumentParser()
self.add_arguments(parser)
return parser
def add_arguments(self, parser):
parser.add_argument('--type', required=True)
parser.add_argument('--update', action='store_true')
parser.add_argument('--optional', default='default')
parser.add_argument('foo')
parser.add_argument('args', nargs='*')
if __name__=='__main__':
testcmd = BaseCommand()
# testcmd.execute('one','tow', three='four')
call_command(testcmd, '--type','typevalue','foovalue', 'argsvalue', update=True)
args = ['--type=argvalue', 'foovalue', '1', '2']
kwargs = {
'solr_url': 'http://127.0.0.1...',
'type': 'opinions',
'update': True,
'everything': True,
}
call_command(testcmd, *args, **kwargs)
产生:
python3 stack32036562.py
args: ('argsvalue',)
kwargs: {'optional': 'default', 'type': 'typevalue', 'update': True, 'skip_checks': True, 'foo': 'foovalue'}
args: ('1', '2')
kwargs: {'optional': 'default', 'update': True, 'foo': 'foovalue', 'type': 'opinions', 'skip_checks': True, 'everything': True, 'solr_url': 'http://127.0.0.1...'}
有了一堆存根,我可以让你的 cl
Command
和我的 BaseCommand
一起工作,并且下面的调用有效:
clupdate = Command()
args = ['--type','opinions','--solr-url','dummy']
kwargs = {
'solr_url': 'http://127.0.0.1:8983/solr/collection1',
#'type': 'opinions',
'update': True,
'everything': True,
'do_commit': True,
'traceback': True,
}
call_command(clupdate, *args, **kwargs)
执行存根 everything
。
Running in update mode...
everything
args: ()
options: {'type': 'opinions', 'query': None, 'solr_url': 'http://127.0.0.1:8983/solr/collection1', 'items': None, 'do_commit': True, 'update': True, 'delete': False, 'datetime': None, 'optimize': False, 'skip_checks': True, 'everything': True, 'traceback': True}
我正在尝试以与 this question without an answer 非常相似的方式使用 Django 的 call_command
。
我的称呼方式是:
args = []
kwargs = {
'solr_url': 'http://127.0.0.1:8983/solr/collection1',
'type': 'opinions',
'update': True,
'everything': True,
'do_commit': True,
'traceback': True,
}
call_command('cl_update_index', **kwargs)
根据 the docs,理论上应该可行。但是不行,就是不行。
这是我的命令 class 的 add_arguments
方法:
def add_arguments(self, parser):
parser.add_argument(
'--type',
type=valid_obj_type,
required=True,
help='Because the Solr indexes are loosely bound to the database, '
'commands require that the correct model is provided in this '
'argument. Current choices are "audio" or "opinions".'
)
parser.add_argument(
'--solr-url',
required=True,
type=str,
help='When swapping cores, it can be valuable to use a temporary '
'Solr URL, overriding the default value that\'s in the '
'settings, e.g., http://127.0.0.1:8983/solr/swap_core'
)
actions_group = parser.add_mutually_exclusive_group()
actions_group.add_argument(
'--update',
action='store_true',
default=False,
help='Run the command in update mode. Use this to add or update '
'items.'
)
actions_group.add_argument(
'--delete',
action='store_true',
default=False,
help='Run the command in delete mode. Use this to remove items '
'from the index. Note that this will not delete items from '
'the index that do not continue to exist in the database.'
)
parser.add_argument(
'--optimize',
action='store_true',
default=False,
help='Run the optimize command against the current index after '
'any updates or deletions are completed.'
)
parser.add_argument(
'--do-commit',
action='store_true',
default=False,
help='Performs a simple commit and nothing more.'
)
act_upon_group = parser.add_mutually_exclusive_group()
act_upon_group.add_argument(
'--everything',
action='store_true',
default=False,
help='Take action on everything in the database',
)
act_upon_group.add_argument(
'--query',
help='Take action on items fulfilling a query. Queries should be '
'formatted as Python dicts such as: "{\'court_id\':\'haw\'}"'
)
act_upon_group.add_argument(
'--items',
type=int,
nargs='*',
help='Take action on a list of items using a single '
'Celery task'
)
act_upon_group.add_argument(
'--datetime',
type=valid_date_time,
help='Take action on items newer than a date (YYYY-MM-DD) or a '
'date and time (YYYY-MM-DD HH:MM:SS)'
)
无论我在这里做什么,我都会得到:
CommandError: Error: argument --type is required
有什么想法吗?如果你真的很好奇,你可以 see the entire code here.
您用 '--type'
标志定义了一个参数,并使其成为 required
。该命令行将需要一个或多个类似于 --type avalue
.
这看起来像 call_command
的相关部分:
def call_command(name, *args, **options):
....
parser = command.create_parser('', name)
if command.use_argparse:
# Use the `dest` option name from the parser option
opt_mapping = {sorted(s_opt.option_strings)[0].lstrip('-').replace('-', '_'): s_opt.dest
for s_opt in parser._actions if s_opt.option_strings}
arg_options = {opt_mapping.get(key, key): value for key, value in options.items()}
defaults = parser.parse_args(args=args)
defaults = dict(defaults._get_kwargs(), **arg_options)
# Move positional args out of options to mimic legacy optparse
args = defaults.pop('args', ())
它创建一个解析器,使用它自己的参数加上您添加的参数。
parser._actions if s_opt.option_strings
是带有选项标志(以 - 或 -- 开头)的参数(操作)。 opt_mapping
是标志字符串(减去前导 -s)和 'dest' 属性之间的映射。
arg_options
将您的 **kwargs
转换为可以与 parser
输出合并的内容。
defaults = parser.parse_args(args=args)
进行实际解析。也就是说,它是唯一实际使用 argparse
解析机制的代码。因此,您调用的 *args
部分模拟从交互式调用中生成 sys.argv[1:]
。
根据阅读的内容,我认为这应该可行:
args = [
'--solr-url', 'http://127.0.0.1:8983/solr/collection1',
'--type', 'opinions',
'--update'
'--everything',
'--do_commit',
'--traceback',
}
call_command('cl_update_index', *args)
而不是 **kwargs
我将值作为字符串列表传递。或者可以在 args
中传递两个 required 参数,其余的在 **kwargs
.
args = ['--solr-url', 'http://127.0.0.1:8983/solr/collection1',
'--type', 'opinions']
kwargs = {
'update': True,
'everything': True,
'do_commit': True,
'traceback': True,
}
call_command('cl_update_index', *args, **kwargs)
如果一个参数是required
,它需要通过*args
传入。 **kwargs
绕过解析器,导致它反对缺少参数。
我已经下载了最新的 django
,但还没有安装。但这里有一个 call_command
的模拟,应该测试调用选项:
import argparse
def call_command(name, *args, **options):
"""
Calls the given command, with the given options and args/kwargs.
standalone simulation of django.core.mangement call_command
"""
command = name
"""
....
"""
# Simulate argument parsing to get the option defaults (see #10080 for details).
parser = command.create_parser('', name)
if command.use_argparse:
# Use the `dest` option name from the parser option
opt_mapping = {sorted(s_opt.option_strings)[0].lstrip('-').replace('-', '_'): s_opt.dest
for s_opt in parser._actions if s_opt.option_strings}
arg_options = {opt_mapping.get(key, key): value for key, value in options.items()}
defaults = parser.parse_args(args=args)
defaults = dict(defaults._get_kwargs(), **arg_options)
# Move positional args out of options to mimic legacy optparse
args = defaults.pop('args', ())
else:
# Legacy optparse method
defaults, _ = parser.parse_args(args=[])
defaults = dict(defaults.__dict__, **options)
if 'skip_checks' not in options:
defaults['skip_checks'] = True
return command.execute(*args, **defaults)
class BaseCommand():
def __init__(self):
self.use_argparse = True
self.stdout= sys.stdout
self.stderr=sys.stderr
def execute(self, *args, **kwargs):
self.handle(*args, **kwargs)
def handle(self, *args, **kwargs):
print('args: ', args)
print('kwargs: ', kwargs)
def create_parser(self, *args, **kwargs):
parser = argparse.ArgumentParser()
self.add_arguments(parser)
return parser
def add_arguments(self, parser):
parser.add_argument('--type', required=True)
parser.add_argument('--update', action='store_true')
parser.add_argument('--optional', default='default')
parser.add_argument('foo')
parser.add_argument('args', nargs='*')
if __name__=='__main__':
testcmd = BaseCommand()
# testcmd.execute('one','tow', three='four')
call_command(testcmd, '--type','typevalue','foovalue', 'argsvalue', update=True)
args = ['--type=argvalue', 'foovalue', '1', '2']
kwargs = {
'solr_url': 'http://127.0.0.1...',
'type': 'opinions',
'update': True,
'everything': True,
}
call_command(testcmd, *args, **kwargs)
产生:
python3 stack32036562.py
args: ('argsvalue',)
kwargs: {'optional': 'default', 'type': 'typevalue', 'update': True, 'skip_checks': True, 'foo': 'foovalue'}
args: ('1', '2')
kwargs: {'optional': 'default', 'update': True, 'foo': 'foovalue', 'type': 'opinions', 'skip_checks': True, 'everything': True, 'solr_url': 'http://127.0.0.1...'}
有了一堆存根,我可以让你的 cl
Command
和我的 BaseCommand
一起工作,并且下面的调用有效:
clupdate = Command()
args = ['--type','opinions','--solr-url','dummy']
kwargs = {
'solr_url': 'http://127.0.0.1:8983/solr/collection1',
#'type': 'opinions',
'update': True,
'everything': True,
'do_commit': True,
'traceback': True,
}
call_command(clupdate, *args, **kwargs)
执行存根 everything
。
Running in update mode...
everything
args: ()
options: {'type': 'opinions', 'query': None, 'solr_url': 'http://127.0.0.1:8983/solr/collection1', 'items': None, 'do_commit': True, 'update': True, 'delete': False, 'datetime': None, 'optimize': False, 'skip_checks': True, 'everything': True, 'traceback': True}