2014-09-21 79 views
1

ModelChoiceField查詢集我有一個ModelForm形式有兩種ModelChoiceField輸入其中child取決於parentDjango的 - 基於父ModelChoiceField

parent = forms.ModelChoiceField(
    widget=forms.Select(attrs=_default_attrs), 
    queryset=Parent.objects.all() 
) 
child = forms.ModelChoiceField(
    widget=forms.Select(attrs=_default_attrs), 
    queryset=Child.objects.none() 
) 

我使用JavaScript通過API來填充孩子。使用上面的代碼,驗證失敗,因爲queryset設置爲無 - 即沒有項目有效。

現在我可以設置querysetChild.objects.all()這將解決驗證問題,但它不實用,因爲child有數千個項目。

我知道,我可以在__init__()覆蓋queryset,這就是我想要做的,但是,不像我搜索計算器在大多數情況下,child是依賴於parent其價值我檢索問題。這是我的嘗試:

def __init__(self, *args, **kwargs): 
    super(NewPostForm, self).__init__(*args, **kwargs) 
    self.fields['child'].queryset = Child.objects.filter(parent=self.fields['parent']) 

這就提出了以下幾點:

int() argument must be a string or a number, not 'ModelChoiceField' 

探索self.fields['parent']

(Pdb) pprint(dir(self.fields['parent'])) 
[... 
'bound_data', 
'cache_choices', 
'choice_cache', 
'choices', 
'clean', 
'creation_counter', 
'default_error_messages', 
'default_validators', 
'empty_label', 
'empty_values', 
'error_messages', 
'help_text', 
'hidden_widget', 
'initial', 
'label', 
'label_from_instance', 
'localize', 
'prepare_value', 
'queryset', 
'required', 
'run_validators', 
'show_hidden_initial', 
'to_field_name', 
'to_python', 
'valid_value', 
'validate', 
'validators', 
'widget', 
'widget_attrs'] 

他們沒有一個是有用的,bound_data看起來像我想要什麼,但即使這樣沒有工作。

我該如何解決這個問題?我需要的是將querysetchild設置爲基於parent的適當子集。

+1

貌似你試圖動態更改值。你不能這樣做,因爲'__init__'是一個初始化器,並且每次值改變時都不會被調用。這篇文章可能會幫助你:http://stackoverflow.com/questions/3233850/django-jquery-cascading-select-boxes – karthikr 2014-09-21 13:57:48

+0

@karthikr'self._raw_value('parent')'爲我做了,謝謝! – abstractpaper 2014-09-21 19:10:44

回答

1

here,我結束了使用self._raw_value('parent')這解決了我的問題。

更新:的Django 1.9去除_raw_value(),這裏是另類:

self.fields['parent'].widget.value_from_datadict(
    self.data, self.files, self.add_prefix('parent') 
) 
0

我想你可以覆蓋modelform的'is_valid'函數。

def is_valid(self): 

     # run the parent validation first 
     valid = super(SomeForm, self).is_valid() 

     if not valid: 
      return valid 

您可以檢查此博客的詳細信息:http://chriskief.com/2012/12/16/override-django-form-is_valid/

+0

我可能會用'clean'來代替。無論如何,爲了驗證'child',我需要'parent'的值,這讓我回到原來的問題 - 無法檢索'parent'的值。 – abstractpaper 2014-09-21 10:05:01