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'に変更するためです。これは、送信ボタンを押したときに表示されるものです。バインドされたメソッドを入力するには、datadictに「name」のみを照会する必要があります。

うーん、これを回避する方法があるかどうかはわかりませんが、この動作は少なくともどこかに文書化する必要があるようです。多分私は何かを誤解しましたか?

于 2010-12-01T18:57:15.340 に答える