测试 Django 命令文件或标准输入

Testing Django commands file or stdin

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

由于数据量的原因,输入应该作为文件或标准输入输入似乎很自然。

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

现在,我记得某个地方(找不到正确记录,but I did find the "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

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

command docs 建议写信给 self.stdout 以便更好地测试。我为 self.stdin 尝试了类似的方法,但也无法正常工作。

当然这是一个常见的模式,但我找不到任何关于如何最好地做到这一点的好帮助。好像是"There should be one-- and preferably only one --obvious way to do it.",但是我找不到。有什么我想念的吗?

查看 the docs add_argument 的 type= 参数,它显示 "the argparse module provides the factory FileType"。

所以我做了以下操作,./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))

Django 命令参数解析器是 argparse module. According to this post: Optional stdin in Python with argparse 的包装,您可以定义一个参数来接受 stdin 或实际文件作为输入。

供您参考的示例命令:

management/commands/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

我不确定您需要什么。如果我误解了,请发表评论。希望对你有帮助。