django multiwidget子类不调用decompress()

发布于 2024-10-05 19:11:51 字数 2164 浏览 4 评论 0原文

我正在尝试为 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一袭水袖舞倾城 2024-10-12 19:11:51

事实证明,问题出在 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',这就是按下提交按钮时得到的结果。为了填充绑定方法,只需要查询 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):

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)]

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文