django modelchoicefield,具有不同的列值

时间:2016-02-29 15:45:17

标签: python django

我想要做的是使用模型表中一列的不同值填充select元素。

my forms.py:

class ExampleForm(forms.ModelForm):
    only_unique_values = forms.ModelChoiceField(
        required = False,
        queryset = ReadOnlyTable.objects.values('pie').distinct(),
        widget = forms.Select
    )

使用values函数会返回ValuesQuerySet而不是QuerySet,这对我的select元素来说是个问题,因为所有选项都填充了字典语法值而不仅仅是列数据string s。

最终看起来像这样

<select id="id_example" name="example_form">
<option value="" selected="selected">---------</option>
<option value="{'pie': u'apple     '}">{'pie': u'apple     '}</option>
<option value="{'pie': u'pecan     '}">{'pie': u'pecan     '}</option>
<option value="{'pie': u'dutch     '}">{'pie': u'dutch     '}</option>
<option value="{'pie': u'pumpkin     '}">{'pie': u'pumpkin     '}</option>
</select>

我希望它看起来像是这样

<select id="id_example" name="example_form">
<option value="" selected="selected">---------</option>
<option value="apple">apple</option>
<option value="pecan">pecan</option>
<option value="dutch">dutch</option>
<option value="pumpkin">pumpkin</option>
</select>

如何从我的模型string电话中返回distinct()个值?

1 个答案:

答案 0 :(得分:2)

模型选择字段用于从模型中选择实例。如果要从模型实例中选择值,则模型选择字段不再适用。

您可以使用选择字段,并在表单的__init__方法中设置选项。

class ExampleForm(forms.ModelForm):
    only_unique_values = forms.ChoiceField(
        required=False,
        choices=[],
        widget=forms.Select,
    )

    def __init__(self, *args, **kwargs):
        super(ExampleForm, self).__init__(*args, **kwargs)
        self.fields['only_unique_values'].choices = ReadOnlyTable.objects.values_list('pie', 'pie').distinct()

执行values_list('pie', 'pie')会为您提供选择字段所需的两元组列表。

在Django 1.8+中,您不再需要覆盖__init__。相反,您可以定义一个返回选项列表的callable,并将callable传递给您的选择字段。

def unique_values():
    return ReadOnlyTable.objects.values_list('pie', 'pie').distinct()

class ExampleForm(forms.ModelForm):
    only_unique_values = forms.ChoiceField(
        required=False,
        choices=unique_values,
        widget=forms.Select,
    )

要在选择字段中包含空白选项,只需将项目添加到选项列表中:

def unique_values():
    return [("", "---------")] + list(ReadOnlyTable.objects.values_list('pie', 'pie').distinct())