【问题标题】:Django's call_command fails with missing required argumentsDjango 的 call_command 因缺少必需的参数而失败
【发布时间】:2015-11-02 08:10:23
【问题描述】:

我想从我的一项测试中调用 Django 管理命令。我为此使用django.core.management.call_command。而且它不起作用。

我有一个带有 4 个必需参数的命令。当我调用它时,它抱怨所有参数都丢失了,即使我正在传递它们:

call_command('my_command', url='12', project='abc', website='zbb', title='12345')

我收到缺少--url、--project、--website 和--title 的基本命令错误。

我没有为这些参数指定不同的目的地。

我查看了call_command 源并将问题定位到call_command 中的以下行:

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)    ****** THIS *****
    defaults = dict(defaults._get_kwargs(), **arg_options)
    # Move positional args out of options to mimic legacy optparse
    args = defaults.pop('args', ())

args 是传递给 call_commands 的位置参数,它是空的。我只传递命名参数。 parser.parse_args 抱怨缺少所需的变量。

这是在 Django 1.8.3 中。

这是我的命令的 add_arguments 函数(为简洁起见,我刚刚删除了帮助字符串):

def add_arguments(self, parser):
    parser.add_argument('--url', action='store', required=True)
    parser.add_argument('--project', action='store', required=True)
    parser.add_argument('--continue-processing', action='store_true', default=False)
    parser.add_argument('--website', action='store', required=True)
    parser.add_argument('--title', action='store', required=True)
    parser.add_argument('--duplicate', action='store_true',default=False)

【问题讨论】:

  • 显示你的命令代码(至少option_list定义)
  • 添加了add_arguments函数源码。
  • 你真的用arg1='12', arg2='abc', arg3='zbb', arg4='12345'关键字参数来称呼它吗?你知道对于选项parser.add_argument('--url') 关键字arg 应该是url 吗?
  • 您在哪里将arg1arg2 等定义为参数?您的电话与https://docs.djangoproject.com/en/1.8/ref/django-admin/#running-management-commands-from-your-code 中的示例不同
  • 我没有用 arg1、arg2 等... 显然。我改变了问题。

标签: python django argparse


【解决方案1】:

根据您发布的那段代码,我在call_command argument is required得出结论

必须通过*args 传递所需的命名参数,而不仅仅是位置。

**kwargs 绕过解析器。所以它看不到你在那里定义的任何东西。 **kwargs 可能会覆盖 *args 值,但 *args 仍然需要为每个必需的参数提供一些东西。如果您不想这样做,请关闭required 属性。

【讨论】:

  • 是的,我在 call_command 的代码中也看到了这一点。这是 call_command 中的一个错误。我无法在 *args 中传递所需的参数 - 它们的正确顺序是什么?也许我调用 add_argument 的顺序,也许是别的东西,也许它取决于操作系统或 Python 版本。我不想冒险。
  • argparse 试图对订单不敏感。
  • 怎么可能可能不敏感?如果我在 args 中输入 '1', '2', '3', '4' ,它怎么知道哪个是 url,哪个是项目等...?
  • url 不是标记参数吗?使用'--url', '1', '--position', '2', ...'--url=1', ...
  • 这个限制应该be fixed soon
猜你喜欢
  • 2015-11-09
  • 1970-01-01
  • 1970-01-01
  • 2015-09-27
  • 2013-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多