Reputation: 106
In django 1.9 i can init MultipleChoiceField with
forms.py
class MyForm(forms.Form):
city = forms.MultipleChoiceField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['city'].choices = City.objects.values_list('id', 'name')
self.initial['city'] = \
City.objects.filter(some_flag=True).values_list('id', flat=True)
In django 1.11 it doesn't work because I have to put tuple or list on Queryset
self.initial['city'] = \
list(City.objects.filter(some_flag=True).values_list('id', flat=True))
I found out, that django.forms.widgets has new class ChoiceWidget with method format_value
def format_value(self, value):
"""Return selected values as a list."""
if not isinstance(value, (tuple, list)):
value = [value]
return [force_text(v) if v is not None else '' for v in value]
Why? In my opinion checking Iterable is better way,
EDIT: Iterable can mess with strings. So we can check if value is QuerySet too.
def format_value(self, value):
"""Return selected values as a list."""
#from collections import Iterable
#if not isinstance(value, Iterable):
from django.db.models.query import QuerySet
if not isinstance(value, (tuple, list, QuerySet)):
value = [value]
return [force_text(v) if v is not None else '' for v in value]
So
Or somebody knows another solution?
PS. Yes, I know, that ModelMultipleChoiceField exists but I have above logic for many fields and don't want refactor all code now.
Upvotes: 2
Views: 2969
Reputation:
class MyForm(forms.ModelForm):
city = City.objects.all()
cities = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, required=True, queryset=city)
class Meta:
model = Team
fields = ('city' )
May be try this ?
Upvotes: 1