2011-04-21 102 views
3
class Test(forms.Form): 

    def set_choices(self, choices): 
     self.choices = choices 

    def get_choices(self): 
     return self.choices 

    options = forms.ChoiceField(choices=get_choices()) 

f = Test() 
f.set_choices(...) 

为什么不可能这样?
我还能如何实现将数据传递到类Test的目标?
在此先感谢。将数据传递到Django窗体

+1

您是否仔细阅读了文档? http://docs.djangoproject.com/en/1.3/topics/forms/ – Nacho 2011-04-21 12:59:14

回答

9

这是一个基本的Python问题。您需要考虑执行这些命令的顺序及其范围。

首先,您定义一个名为Test的表单类。该类有三个属性:set_choices方法,get_choices方法和options字段。这些定义在类定义时进行评估。 options的定义调用get_choices()。但是,此时在范围内没有get_choices方法,因为该类尚未定义。

即使您以某种方式设法排除了范围问题,但这仍然无法达到您想要的效果,因为options的选择定义是在定义时完成的。即使您稍后致电set_choicesoptions仍然具有在定义该字段时返回的值get_choices

那么,你究竟想要做什么?看起来你想在options字段上设置动态选项。所以,你应该覆盖__init__方法并在那里定义它们。

class Test(forms.Form): 
    options = forms.ChoiceField(choices=()) 

    def __init__(self, *args, **kwargs): 
     choices = kwargs.pop('choices', None) 
     super(Test, self).__init__(*args, **kwargs) 
     if choices is not None: 
      self.fields['options'].choices = choices 
+0

那么如何在视图中使用测试表单时通过这些选择? – 2016-07-27 08:42:07

+0

我不确定你在问什么。但你当然应该问一个新问题,而不是评论一个五年的答案。 – 2016-07-27 08:56:26

0

扩展__init__是选择动态地添加到ChoiceField为丹尼尔罗斯曼在his answer解释了一个好办法。

只是添加到...在运行时添加选项是hackish(最好)。这里是音符的最佳做法(直接从Django ChoiceField documentation) -

最后,要注意选择可以是任何 迭代的对象 - 不一定是 列表或元组。这使您可以动态构造 选项。但是如果你发现自己的黑客选择是 动态,你可能会更好 使用适当的数据库表和 ForeignKey。如果有的话, 静态数据的变化不大, 。