подкласс мультивиджетов django не вызывает depress () - PullRequest
1 голос
/ 01 декабря 2010

Я пытаюсь реализовать записи MultiValueField для IP-адреса / доменного имени. Это работает, как ожидается, для ввода данных. Моя проблема заключается в том, что если я хочу отобразить форму, привязанную к конкретным данным, поле 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 в свой метод сжатия, и мне так и не удалось увидеть это утверждение. Кроме того, если я переименую сжатие в нечто вроде foobar, я ожидаю (согласно коду django для MultiWidget) получить NotImplementedError, что не так. Есть предложения?

Я использую python 2.6.5, django 1.1 на сервере Ubuntu 10.04.

1 Ответ

1 голос
/ 01 декабря 2010

Оказывается, проблема была в методе value_from_datadict (), реализованном в MultiWidget.Прежде всего, он уже вернул список, поэтому не вызывался метод deppress ().Во-вторых, он всегда восстанавливал список [Нет, Нет], поэтому связанная форма осталась пустой.

Мне нужно было реализовать свою собственную (в моем классе 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', которое вы получаете, нажимая кнопку отправки.Чтобы заполнить связанный метод, запрос данных должен быть запрошен только для «имени».

Хм, не уверен, есть ли способ обойти это, но мне кажется, что это поведение должно по крайней меребыть где-то задокументировано.Может я что то не так понял?

...