测试Django命令文件或stdin

时间:2017-02-14 00:36:09

标签: python django django-commands

我正在编写一个django命令,它接受一堆输入并处理它。

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

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

现在,我记得某个地方(无法正确记录,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尝试过类似的东西,但也无法使其工作。

确实这是一个常见的模式,但我找不到任何有关如何做到最好的好帮助。似乎“应该有一个 - 最好只有一个 - 明显的方式来做它。”,但我找不到它。有什么我想念的吗?

2 个答案:

答案 0 :(得分:2)

查看the docs add_argument的type=参数,它说" argparse模块提供工厂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))

答案 1 :(得分:2)

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

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