我正在尝试为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语句,我从来没有看到过这个语句。此外,如果我将压缩重命名为foobar之类的东西,我希望(根据MultiWidget的django代码)获取NotImplementedError,但事实并非如此。有什么建议吗?
我在ubuntu服务器10.04上使用python 2.6.5,django 1.1。
答案 0 :(得分: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方法仅适用于未绑定的字段。因为它将原始字段的名称更改为名称+'_%s',这是您按下提交按钮时获得的名称。为了填写绑定方法,需要仅为“名称”查询datadict。
嗯,如果有办法可以解决这个问题,但在我看来,这种行为至少应该记录在某个地方。 也许我误会了什么?