2

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

  • solution 1: put list() on queryset with values_list('id', flat=True)
  • solution 2: monkey patching Widget for MultipleChoiceField

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.

warcholprzemo
  • 106
  • 1
  • 7

1 Answers1

1
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 ?

  • This does not solve the problem. Problem is in the initialization of MultipleChoiceField. QuerySet is example of other iterable structures like generator or itertools.chain. – warcholprzemo Aug 17 '17 at 10:30