繁体   English   中英

构建Django表单/类方法的正确方法

[英]Proper way to build Django form/class method

我有一个Django表单(Django非相关v1.5.5),该表单/类方法工作正常。 但是,现在我开始为应用程序构建单元测试,但是在测试表单/类方法时遇到了问题。 我认为表单/类方法定义不正确。

表格

class TimeForm(forms.Form):
    def build_choices(start, stop, incr=1):
        # Form/class method that builds a list of tuples of identical i, i values for forms.ChoiceField
        choice_list = []
        temp_list   = [i for i in range(start, stop, incr)]

        for i in temp_list:
            choice_list.append(('%02d' % i, '%02d' % i))

        return choice_list

    hour_choices   = build_choices(1, 13) # E.g., [('01', '01'), ('02', '02') ... ]
    minute_choices = build_choices(0, 60, 15)
    hour     = forms.ChoiceField(choices=hour_choices)
    minute   = forms.ChoiceField(choices=minute_choices)

上面的代码可以很好地生成表单,并为表单字段选择适当的位置。 但是,当我尝试对build_choices方法进行单元测试时,我遇到了build_choices

一些测试

"""Testing the build_choices method."""
> form = TimeForm()
> form.build_choices(1, 10) # This will not work.
> *** TypeError: range() integer start argument expected, got TimeForm.
>
> TimeForm.build_choices(1, 10) # This will not work.
> *** TypeError: unbound method build_choices() must be called with TimeForm instance as first argument (got int instance instead)
>
> TimeForm.build_choices(form, 1, 10)
> *** TypeError: range() integer start argument expected, got TimeForm.

然而,

> TimeForm.hour_choices
> [('01', '01'), ('02', '02') ... ]

有没有更好的方法/正确的方法来定义不是实例方法的form方法? 例如, TimeForm(self, start, end, inc)

这是一些奇怪的设置。 您有一个类方法,该方法立即作为普通函数调用,直到类完成初始化为止。

我不是一个深奥的python向导,但似乎只有在安装类之后,函数才会转换为类方法。

底线: TimeForm.build_choices是一个类方法。 它的第一个参数始终是类实例。

解:

在类之外定义build_choices

通过TimeForm.hour_choices.__func__(1, 10)测试功能对象本身

我认为与Tomita一样,在类初始化之前, build_choices是一个函数,在它之后,它是一个实例方法。 我认为另一种选择是将build_choices放在build_choices之外,而不是:

class TimeForm(forms.Form):
    def build_choices(self, start, stop, incr=1):
        # Form/class method that builds a list of tuples of identical i, i values for forms.ChoiceField
        choice_list = []
        temp_list   = [i for i in range(start, stop, incr)]

        for i in temp_list:
            choice_list.append(('%02d' % i, '%02d' % i))

        return choice_list

    hour_choices   = build_choices(None, 1, 13) # E.g., [('01', '01'), ('02', '02') ... ]
    minute_choices = build_choices(None, 0, 60, 15)
    hour     = forms.ChoiceField(choices=hour_choices)
    minute   = forms.ChoiceField(choices=minute_choices)

在这种情况下(如您的示例),在测试中您将无法将build_choices作为类方法调用(为此,您将需要使用装饰器@classmethod或@staticmethod,但如果这样做,您将无法调用它来自类属性)。

您可以在他进行如下测试时调用它:

form = TimeForm()
form.build_choices(1, 10)
TimeForm.build_choices(TimeForm(), 1, 10)
TimeForm.build_choices(form, 1, 10)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM