Django SelectMultiple 小部件的动态选择
Posted
技术标签:
【中文标题】Django SelectMultiple 小部件的动态选择【英文标题】:Dynamic choices for Django SelectMultiple Widget 【发布时间】:2011-02-07 02:02:51 【问题描述】:我正在构建一个表单(不是 modelForm),我想使用 SelectMultiple 小部件根据表单初始化期间完成的查询来显示选择。
我可以想到几种方法来做到这一点,但我并不完全清楚正确的方法。我看到了不同的选择。
我得到了我应该以 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))
【问题讨论】:
【参考方案1】:为什么不改用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()
这样,您不仅可以限制小部件上的可用选项,还可以限制字段上的可用选项(这为您提供数据验证)。
使用此方法,小部件中显示的字符串将是Language
对象上的__unicode__
方法的结果。如果这不是您想要的,您可以编写以下自定义字段,如 ModelChoiceField
reference 中所述:
class LanguageMultipleChoiceField(forms.ModelMultipleChoiceField):
def label_from_instance(self, obj):
return obj.language_code # for example, depending on your model
并在您的表单中使用此类而不是 ModelMultipleChoiceField
。
【讨论】:
我见过提到 ModelMultipleChoiceField,但不确定它的用途。现在正在尝试。谢谢。 完美运行,看起来比我的干净一点。再次感谢 mmm 实际上,我在验证表单时收到“AttributeError: 'unicode' object has no attribute 'get'”。我的语言模型确实是一个 char 字段... 您必须提供有关此错误的更多详细信息,它发生在哪个文件中?上下文是什么?它可能来自您清理或操作表单中已清理数据的方式吗?另外,您的意思是:我的语言模型确实是一个字符字段...?【参考方案2】: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,小部件也只会显示选项的第一个字母...
【讨论】:
choices 必须是以下元组的列表/元组 (int_or_str_key, 'name')以上是关于Django SelectMultiple 小部件的动态选择的主要内容,如果未能解决你的问题,请参考以下文章