2012-12-27 31 views
0

我已經真的拉我的頭髮來完成這件事。我在我的車型之一2個整型字段如下:有可能是多小部件使用兩種不同的模式場

#models.py 

class TestModel(models.Model): 
    """ 
    This is a test model. 
    """ 

    max = models.IntegerField() 
    min = models.IntegerField() 

由於上述兩個值是相互關聯的我想讓他們使用自定義窗口小部件。現在這裏是關鍵點,我希望這些字段使用單個自定義小部件(MultiWidget),但我也想將這些值保存在數據庫中的不同列中[不是真正想要解析的東西,而且搜索功能將使用上面的字段分開,所以只想分開存儲]。

甲定製窗口小部件將只接受來自單一模式字段值,所以我決定創建自定義表單字段中的ModelForm用於上述模型。

現在,這是我的表單外觀。

class MinMaxField(forms.MultiValueField): 

    def __init__(self, *args, **kwargs): 

     all_fields = ( 
      forms.CharField(), 
      forms.CharField(), 
      ) 

     super(MinMaxField, self).__init__(all_fields, *args, **kwargs) 

    def compress(self, values): 
     if values: 
      return '|'.join(values) 
     return '' 

class TestModelForm(forms.ModelForm): 

    minmax = MinMaxField(widget=widgets.MinMaxWidget(), 
      required=False) 

    class Meta: 
     model = models.TestModel 
     fields = ('min', 'max', 'minmax') 
     widgets = { 
      'min' : forms.HiddenInput(), 
      'max' : forms.HiddenInput(), 
     } 

    def full_clean(self, *args, **kwargs): 
     if 'minmax_0' in self.data: 
      newdata = self.data.copy() 
      newdata['min'] = self.data['minmax_0'] 
      newdata['max'] = self.data['minmax_1'] 
      self.data = newdata 
     super(TestModelForm, self).full_clean(*args, **kwargs) 

上述基本形成隱藏示範田,並只顯示一個使用自定義窗口小部件如下minmax領域:

class MinMaxWidget(widgets.MultiWidget): 

    def __init__(self, attrs=None): 
     mwidgets = (widgets.Select(attrs=attrs, choices=MIN), 
        widgets.Select(attrs=attrs, choices=MAX)) 
     super(MinMaxWidget, self).__init__(mwidgets, attrs) 

    def value_from_datadict(self, data, files, name): 
     try: 
      values = [widget.value_from_datadict(data, files, name + '_%s' % i)\ 
         for i, widget in enumerate(self.widgets)] 

      value = [int(values[0]), int(values[1])] 
     except ValueError: 
      raise ValueError('Value %s for %s did not validate. \ 
           a list or a tuple expected' % (value, self.widget)) 
     return value 

    def decompress(self, value): 
     if value: 
      if isinstance(value, list): 
       return value 
      return [value[0], value[1]] 
     return [None, None] 

    def format_output(self, rendered_widgets): 
     rendered_widgets.insert(0, '<span class="multi_selects">') 
     rendered_widgets.insert(-1, '<label id="min">Min</label>') 
     rendered_widgets.append('<label id="max">Max</label></span>') 
     return u''.join(rendered_widgets) 

現在,在這一點上一切正常,價值觀得到單獨保存成他們各自的領域。但是當我試圖用一個TestModel對象的實例編輯窗體時出現問題。在編輯的情況下,表單呈現時,實際值將存儲在隱藏的minmax輸入字段中,而最小值最大值字段沒有值。 [ofcourse因爲它是一個形式字段。]

什麼是

  1. 我有選擇要麼預先填充從minmax字段minmax表單字段的值。 [注:不使用JavaScript或jQuery的]

  2. 或者創建一個從兩個不同的模型使用的字段的值的MultiWidget。

任何幫助,將不勝感激。謝謝。

+0

你使用的是什麼版本? –

+0

有沒有人找到一種方法來做到這一點...同樣的問題在這裏... – gabn88

回答

0

我目前所面臨類似的問題,並沒有使用插件的兩個字段的方式。 我正在使用1.4版本,並沒有嘗試任何其他。

在你看來,你可能有這樣的事情:

form = TestModelForm(instance=instance) 

其中instance是從數據庫要編輯的對象。 讓我們看看當它創建表單

# django/forms/models.py 

class BaseModelForm(BaseForm): 
    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, 
        initial=None, error_class=ErrorList, label_suffix=':', 
        empty_permitted=False, instance=None): 
      ... 
      if instance is None: 
       ... 
      else: 
       self.instance = instance 
       object_data = model_to_dict(instance, opts.fields, opts.exclude) 
      # if initial was provided, it should override the values from instance 
      if initial is not None: 
       object_data.update(initial) 
      ... 
      super(BaseModelForm, self).__init__(data, files, auto_id, prefix, 
               object_data, error_class, 
               label_suffix, empty_permitted) 

然後,當形式呈現,BoundField類使用這個object_data初始值分配給控件什麼Django的做。

因此,所有你需要做的是在你的表單構造提供initial

class TestModelForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     if 'instance' in kwargs: 
      initial = dictionary with initial values 
      initial.update(kwargs['initial'] or {}) 
     ... 
     super(TestModelForm, self).__init__(initial=initial, *args, **kwargs) 

還記得要添加您的字段到您的表格fields列表。

這樣你就沒有兩個未使用的隱藏小部件,不需要使用javascript和imo,代碼更具說明性。

相關問題