1

我正在尝试为 IP 地址/域名条目实现 MultiValueField。它按预期工作以输入数据。我的问题是,如果我想显示绑定到特定数据的表单,IP 地址/域名字段保持为空。所有其他字段都填充了所需的数据。如果我使用普通的 CharField,我会得到我期望的数据。但它不适用于我的自定义字段。我已经追踪到我的自定义 MultiWidget 没有调用它的解压缩方法这一事实。

这是我的领域:

class accessIPField(forms.MultiValueField):
    """                                                                         
    custom Field for access IP                                                  
    """                                                                         

    def __init__(self, *args, **kwargs):                                        
        self.fields=(                                                           
            forms.IPAddressField(label='IP Adress'),                            
            forms.CharField(max_length=50,label='Domain Name')                  
        )                                                                       
        self.widget=accessIPWidget()                                            
        super(accessIPField,self).__init__(self.fields,self.widget, *args, **kwargs)

    def compress(self,data_list):                                               
        if data_list:                                                           
            return " ".join(data_list) 

这是我的小部件:

class accessIPWidget(forms.MultiWidget):
    """ 
    Widget to display IP Adress / Domain name pairs
    """
    def __init__(self,*args,**kwargs):
        self.widgets=(forms.TextInput(),forms.TextInput())
        super(accessIPWidget,self).__init__(self.widgets,*args,**kwargs)

    def decompress(self,value):
        print 'decompress called'
        if value:
            return value.rsplit()
        return [None,None]

    def format_output(self, rendered_widgets):
        return u'\n'.join(rendered_widgets)

整个事情被称为(在更大的背景下)为

self.fields['access_IPs'] = accessIPField()

现在你可以看到,我在我的 compress 方法中放了一个 print 语句,但我永远看不到那个语句。此外,如果我将 compress 重命名为 foobar 之类的名称,我希望(根据 MultiWidget 的 django 代码)得到 NotImplementedError,但事实并非如此。有什么建议么?

我在 ubuntu 服务器 10.04 上使用 python 2.6.5、django 1.1。

4

1 回答 1

1

事实证明,问题出在 MultiWidget 实现的 value_from_datadict() 方法上。首先,它已经返回了一个列表,所以这就是为什么首先没有调用 decompress() 的原因。其次,它总是返回一个 [None,None] 列表,这就是绑定表单保持为空的原因。

我需要实现自己的(在我的 accessIPWidget 类中):

def value_from_datadict(self, data, files, name):
try:
  return data.get(name,None).rsplit()
except AttributeError:
  return [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)]

现在最后一行是原始方法所做的。为了将数据放入绑定表单,我需要添加 data.get(name,None).rsplit()。

据我了解,原始 value_from_datadict 方法仅适用于未绑定字段。因为它将原始字段的名称更改为 name + '_%s',这是您按下提交按钮时得到的。为了填写绑定方法,只需要查询数据字典的“名称”。

嗯,不知道是否有办法解决这个问题,但在我看来,这种行为至少应该记录在某个地方。也许我误解了什么?

于 2010-12-01T18:57:15.340 回答