在 django 1.9 中,我可以使用
表格.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 可能会弄乱字符串。所以我们也可以检查 value 是否也是 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 为 MultipleChoiceField 修补 Widget
或者有人知道另一种解决方案?
PS。是的,我知道 ModelMultipleChoiceField 存在,但我对许多字段都有上述逻辑,现在不想重构所有代码。