使用queryset

时间:2017-08-17 07:30:14

标签: python django django-forms django-1.11

在django 1.9中,我可以使用

初始化MultipleChoiceField

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)

在django 1.11中,它不起作用,因为我必须在Queryset上放置元组或列表

self.initial['city'] = \
    list(City.objects.filter(some_flag=True).values_list('id', flat=True))

我发现,django.forms.widgets有一个新类ChoiceWidget,方法是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]

为什么呢?在我看来,检查Iterable是更好的方法,

编辑:Iterable可以搞乱字符串。所以我们也可以检查值是否也是QuerySet。

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]

所以

  • 解决方案1:将list()放在带有values_list的查询集上(' id',flat = True)
  • 解决方案2:使用Monkey Patching Widget for MultipleChoiceField

或者有人知道另一种解决方案?

PS。是的,我知道,ModelMultipleChoiceField存在,但我对许多字段都有逻辑,并且现在不想重构所有代码。

1 个答案:

答案 0 :(得分:0)

class MyForm(forms.ModelForm):
    city = City.objects.all()
    cities = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, required=True, queryset=city)
    class Meta:
        model = Team
        fields = ('city' )

可以尝试一下吗?