我真的一直在拔头发来完成这件事。我的一个模型中有 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
对象的实例编辑表单时,问题就出现了。在编辑的情况下,当呈现表单时,实际值存储在隐藏字段min
和max
输入字段中,而 minmax 字段没有值。[当然,因为它是一个表单域。]
我有什么选择
从和字段中预填充
minmax
表单字段的值。[注意:不使用 Javascript 或 jQuery]min
max
或者创建一个使用来自两个不同模型字段的值的 MultiWidget。
任何帮助,将不胜感激。谢谢。