What I'd like to do is populate a select
element with distinct values from one column in the model table.
my forms.py:
class ExampleForm(forms.ModelForm):
only_unique_values = forms.ModelChoiceField(
required = False,
queryset = ReadOnlyTable.objects.values('pie').distinct(),
widget = forms.Select
)
Using the values
function returns a ValuesQuerySet
instead of a QuerySet
, which is a problem for my select
element because all the options are populated with the dictionary syntax as the values instead of just the column data as string
s.
It ends up looking like this:
<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>
How I would want it to look is like so:
<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>
How can I return string
values from a distinct()
call on my model?
A model choice field is for selecting instances from your model. If you are selecting values from the model instances, then a model choice field isn't suitable any more.
You can use a choice field instead, and set the choices in the form's __init__
method.
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()
Doing values_list('pie', 'pie')
give you the list of two-tuples required by the choice field.
In Django 1.8+, you don't need to override __init__
any more. Instead, you can define a callable that returns the list of choices, and pass the callable to your choice field.
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,
)
To include a blank option in your choice field, just add an item to the list of choices:
def unique_values():
return [("", "---------")] + list(ReadOnlyTable.objects.values_list('pie', 'pie').distinct())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With