具有不同列值的django modelchoicefield

smi*_*omb 5 python django

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

我的表单.py:

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

使用该values函数返回 aValuesQuerySet而不是 a QuerySet,这对我的元素来说是一个问题select,因为所有选项都使用字典语法作为值填充,而不仅仅是列数据作为strings 。

它最终看起来像这样

<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>
Run Code Online (Sandbox Code Playgroud)

我希望它看起来像这样

<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>
Run Code Online (Sandbox Code Playgroud)

如何从模型调用中返回string值?distinct()

Ala*_*air 4

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

您可以改用选择字段,并在表单的方法中设置选项__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()
Run Code Online (Sandbox Code Playgroud)

这样做values_list('pie', 'pie')会给你选择字段所需的二元组列表。

在 Django 1.8+ 中,您不需要__init__再重写。相反,您可以定义一个返回选项列表的可调用对象,并将该可调用对象传递到您的选择字段。

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,
    )
Run Code Online (Sandbox Code Playgroud)

要在您的选择字段中包含空白选项,只需将一个项目添加到选项列表中即可:

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