2011-07-15 80 views
3

所以我正在一個Django應用程序中,我有一個模型事件。每個事件都有一些屬性,比如說其中一個是「主機名」(我將作爲一個例子使用)。我需要實現搜索功能,用戶可以搜索主機名== some_value的所有事件,例如主機名==「myhost.foo.bar」。Django ModelChoiceField使用來自一個模型屬性的不同值

現在,我想允許用戶在搜索表單的組合框中選擇有效選項(即實際存在於一個或多個事件中的主機名),因此我使用ModelChoiceFields作爲我的表單。我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) 

這工作,但這個名單中只填入一次,所以它不是最新的與數據庫。

那麼......有沒有解決這個問題的好方法?回顧一下問題:我如何使用模型的一個字段中的不同值填充組合框,並使其與數據庫保持同步?我認爲ModelChoiceField是最好的選擇,如果我可以在使用.values(...)或.values_list(...)時驗證它。

真誠, Hallgeir

回答

7

第二種方法將工作,但您需要設置初始化的選擇所以它的每個窗體調用時刷新。

e.g

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() 
+0

啊哈,太棒了!謝謝! :) 這完美的作品。 – Hallgeir

相關問題