所以我正在开发一个django应用程序,我有一个模型事件。每个事件都有一些属性,比如其中一个是“hostname”(我将在整个过程中使用它作为例子)。我需要实现搜索功能,用户可以在其中搜索具有hostname == some_value的所有事件,例如hostname ==“myhost.foo.bar”。
现在,我想允许用户在搜索表单的组合框中选择有效选项(即一个或多个事件中实际存在的主机名),因此我将ModelChoiceField用于我的表单。我的ModelChoiceView的子类,用于显示正确的标签:
class HostnameModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return obj.host.hostname
我的表格:
class QueryForm(forms.Form):
hostname = HostnameModelChoiceField(queryset=Event.objects.all(), required=False)
...
但是,这会产生重复,因为许多事件可能具有相同的主机名。我尝试在查询集上使用“distinct()”,但当然这不起作用,因为对象是不同的(即使显示的值不是)。
所以,我试图只选择我需要的值:
class QueryForm(forms.Form):
hostname = ModelChoiceField(queryset=Event.objects.all().values_list("hostname", "hostname").distinct(), required=False)
但这不会验证!我怀疑因为这些值不是实际的事件实例,而只是字符串值。
所以我尝试了一个常规的ChoiceField:
hostname = forms.ChoiceField(choices=Event.objects.all().values_list("hostname", "hostname").distinct(), required=False)
这样可行,但这个列表只填充一次,所以它与数据库不是最新的。
那么......有什么好方法可以解决这个问题吗?回顾一下这个问题:如何使用模型的某个字段中的不同值填充组合框,并使其与数据库保持同步?如果我可以在使用.values(...)或.values_list(...)时进行验证,我认为ModelChoiceField是最好的选择。
此致 Hallgeir
答案 0 :(得分:7)
第二种方法可行,但您需要在 init 上设置选项,以便每次调用表单时刷新它。
例如
class QueryForm(forms.Form):
hostname = forms.ChoiceField(choices=[], required=False)
def __init__(self, *args, **kwargs):
super(QueryForm, self).__init__(*args, **kwargs)
self.fields['hostname'].choices = Event.objects.all().values_list("hostname","hostname").distinct()