django multiwidget子类不调用decompress()
我正在尝试为 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()
现在,如您所见,我在我的压缩方法中放置了一条 print 语句,但我从未看到该语句。另外,如果我将 compress 重命名为 foobar 之类的名称,我希望(根据 MultiWidget 的 django 代码)得到 NotImplementedError,但事实并非如此。有什么建议吗?
我在 ubuntu 服务器 10.04 上使用 python 2.6.5、django 1.1。
I am trying to implement a MultiValueField for IP Adress/Domain Name entries. It works as expected for entering data.
My Problem is that if I want to display the form bound to specific data, the IP Address/Domain Name field stays empty. All other fields are filled with the desired data. If I use a normal CharField, I get the data that I would expect. But it does not work with my custom field.
I have tracked it down to the fact that my custom MultiWidget does not call its decompress method.
Here is my Field:
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)
And here is my widget:
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)
The whole thing is called (in a larger context) as
self.fields['access_IPs'] = accessIPField()
Now as you can see, I put a print statement in my compress method, and I never get to see that statement. Also, if I rename compress to something like foobar, I would expect (according to the django code for MultiWidget) to get the NotImplementedError, which is not the case. Any suggestions?
I am using python 2.6.5, django 1.1 on ubuntu server 10.04.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明,问题出在 MultiWidget 实现的 value_from_datadict() 方法上。首先,它已经返回了一个列表,所以这就是为什么 decompress() 没有被调用。其次,它总是返回一个 [None,None] 列表,这就是绑定表单保持为空的原因。
我需要实现我自己的(在我的 accessIPWidget 类中):
现在最后一行是原始方法的作用。为了将数据获取到绑定表单中,我需要添加 data.get(name,None).rsplit()。
据我了解,原始 value_from_datadict 方法仅适用于未绑定字段。因为它将原始字段的名称更改为 name + '_%s',这就是按下提交按钮时得到的结果。为了填充绑定方法,只需要查询 datadict 的“名称”。
嗯,不确定是否有办法解决这个问题,但在我看来,这种行为至少应该记录在某处。
也许我误解了什么?
It turns out that the problem was with the value_from_datadict() method as implemented by MultiWidget. First of all, it allready returned a list, so that is why decompress() was not called in the first place. Secondly, it allways returen a [None,None] list, so that is why the bound form stayed empty.
I needed to implement my own (within my accessIPWidget class):
Now the last line is what the original method did. In order to get the data into the bound form, I needed to add data.get(name,None).rsplit().
As far as I understand, the original value_from_datadict method only works for unbound fields. Because it changes the name of the original field to name + '_%s', which is what you get when pressing the submit button. In order to fill in a bound method, the datadict needs to be queried for 'name' only.
Hm, not shure if there is a way around this, but it seems to me that this behaviour should at least be documented somewhere.
Maybe I misunderstood something?