1

我正在编写一个 django 命令,它需要大量输入并对其进行处理。

由于数据量大,输入应该以文件或标准输入的形式出现,这似乎很自然。

我想轻松地测试它,我的意思是轻松地,而不必在我的测试环境中创建一堆文件。

现在,我记得某处(找不到正确的文档,但我确实找到了“PR”),“-”应该从标准输入读取,但我无法让它工作。

似乎该命令应该执行以下操作:

class Command(BaseCommand):
    def add_arguments(self, parser):
        parser.add_argument("foo", type=file)

    def handle(self, *args, **options):
        file = options["foo"]
        # Then read the file, and process it

但是当我在命令行上运行命令时,它不喜欢-参数(说它不是文件)。

命令文档建议写入以self.stdout进行更好的测试。我尝试了类似的东西,self.stdin但也无法让它发挥作用。

当然这是一种常见的模式,但我找不到任何关于如何做到最好的帮助。似乎“应该有一种——最好只有一种——明显的方法。”,但我找不到。有什么我想念的吗?

4

2 回答 2

3

查看add_argument 参数的文档,它说“argparse 模块提供工厂 FileType”。type=

所以我做了以下事情,./manage.py test_stdin -然后按照你的预期工作。

import argparse

class Command(BaseCommand):
    def add_arguments(self, parser):
        parser.add_argument("foo", type=argparse.FileType('r'))

    def handle(self, *args, **options):
        input_file = options["foo"]
        while True:
            line = input_file.readline()
            if len(line.strip()) == 0:
                break
            else:
                self.stdout.write("I just read %d chars, line %s" % (len(line),line))
于 2017-02-14T01:15:27.673 回答
3

Django 命令参数解析器是argparse模块的包装。根据这篇文章:Optional stdin in Python with argparse,您可以定义一个接受的参数stdin或一个实际文件作为输入。

示例命令供您参考:

管理/命令/stdintest.py

from django.core.management.base import BaseCommand
import sys
import argparse


class Command(BaseCommand):
    help = 'Test stdin as input file'

    def add_arguments(self, parser):
        parser.add_argument('foo', nargs='?', type=argparse.FileType('r'), default=sys.stdin)

    def handle(self, *args, **options):
        foo = options.get('foo')
        sys.stdout.write(foo.read())

您可以在不指定输入文件的情况下调用该命令,该命令将从 stdin 获取输入

$ python manage.py stdintest
1234
abcd     <- press ctrl+d to end stdin input
1234
abcd

或使用foo实际文件指定参数

$ echo '12345' > test.txt
$ python manage.py stdintest test.txt

我不确定这是你需要的。如果我有误解,请发表评论。希望它会有所帮助。

于 2017-02-14T01:15:58.593 回答