我正在构建一个表单(而不是modelForm),我想使用SelectMultiple Widget根据在表单初始化期间完成的查询来显示选项。
我可以想到一些方法来做到这一点,但我并不清楚正确的做法。我看到了不同的选择。
我得到了“选择”,我应该以 init 的形式传递给小部件,但我不确定应该如何传递它们。
class NavigatorExportForm(forms.Form):
def __init__(self,user, app_id, *args,**kwargs):
super (NavigatorExportForm,self ).__init__(*args,**kwargs) # populates the form
language_choices = Navigator.admin_objects.get(id=app_id).languages.all().values_list('language', flat=True)
languages = forms.CharField(max_length=2, widget=forms.SelectMultiple(choices=???language_choices))
答案 0 :(得分:6)
为什么不使用ModelMultipleChoiceField
?
你可以做到这一点:
class NavigatorExportForm(forms.Form):
languages = forms.ModelMultipleChoiceField(queryset=Language.objects.all())
def __init__(self, app_id, *args, **kwargs):
super(NavigatorExportForm, self).__init__(*args, **kwargs)
# Dynamically refine the queryset for the field
self.fields['languages'].queryset = Navigator.admin_objects.get(id=app_id).languages.all()
这样,您不仅可以限制窗口小部件上的可用选项,还可以限制字段(为您提供数据验证)。
使用此方法,窗口小部件中显示的字符串将是__unicode__
对象上Language
方法的结果。如果它不是您想要的,您可以编写以下自定义字段,如ModelChoiceField
reference中所述:
class LanguageMultipleChoiceField(forms.ModelMultipleChoiceField):
def label_from_instance(self, obj):
return obj.language_code # for example, depending on your model
并在表单中使用此类而不是ModelMultipleChoiceField
。
答案 1 :(得分:0)
def __init__(self,user, app_id, *args,**kwargs):
super (NavigatorExportForm,self ).__init__(*args,**kwargs)
self.fields['languages'].widget.choices = Navigator.admin_objects.get(id=app_id).languages.all().values_list('language', flat=True)
似乎可以解决问题,但即使没有指定max_length,小部件也只显示选择的第一个字母......