2012-03-08 66 views
0

我使用的是django 1.2 我有兩種模式。如何在django中限制ForeignKey

編輯:我剛剛找到一個更好的例子:

class Parent(models.Model): 
    name = models.CharField(max_length=255) 
    favorite_child = models.ForeignKey(Child) 

class Child(models.Model): 
    name = models.CharField(max_length=255) 
    myparent = models.ForeignKey(Parent) 

在這個例子中我希望能夠選擇一個最喜歡孩子,但問題是,管理員會給我所有的孩子們選擇而不僅僅是那些我正在編輯的父母的孩子。

原來的例子:

class Version(models.Model): 
    name = models.CharField(max_length = 255) 
    platform = models.ForeignKey("Platform",related_name='version_platform') 

class Platform(models.Model): 
    name = models.CharField(max_length = 255) 
    default_version = models.ForeignKey(Version,related_name='platform_default_version') 

我想Django管理限制下拉當我選擇default_version,這樣我只能選擇對自己目前的平臺這些版本。
例如,如果我有版本命名爲'1.1',有平臺joomla和版本'1.2'的wordpress作爲平臺。
所以當我選擇default_version在WordPress的管理下拉我想它只顯示我版本'1.2'的下拉列表中。現在它向我展示了所有的版本。

我試圖limit_choices_to限制如圖here ,所以我試試這個:

class Platform(models.Model): 
    name = models.CharField(max_length = 255) 
    default_version = models.ForeignKey(Version,limit_choices_to={'platform':XXXXX},related_name='platform_default_version') 

,但我失去了,什麼把insted的XXXX的我嘗試把自己的,但沒有奏效。
我也曾嘗試

limit_choices_to={'platform.name':name} 

我沒有工作,要麼。

在這個例子中

我想可以選擇一個最喜歡的孩子,但問題是,管理員會給予我的一切誰是我目前編輯父母的孩子的孩子可以選擇,而不僅僅是那些。

+1

limit_choices_to不與動態值正常工作,請參見http://計算器。com/questions/1968596/django-limit-choices-this-this-correct我不知道這是否會幫助你的情況,因爲我猜這是在添加一個新的平臺不編輯? – JamesO 2012-03-08 15:08:46

+0

關於你的第二個例子,你寧願爲你的孩子設置一個'favorite'布爾字段,然後你會使用'unique_together'。 – 2012-03-08 15:38:48

+0

但是然後我將能夠選擇2個最喜歡的孩子,這些孩子會犯錯誤的空間。 – yossi 2012-03-08 15:43:33

回答

2

我發現了一個解決方案基於Django: accessing the model instance from within ModelAdmin?

增加了admin.py 解決方案:

class ParentForm(ModelForm): 
def __init__(self, *args, **kwargs): 
    super(ParentForm, self).__init__(*args, **kwargs) 
    self.fields['favorite_child'].queryset = \ 
    Child.objects.filter(parent=self.instance.pk) 

class ParentAdmin(admin.ModelAdmin): 
    form = ParentForm 
2

你可以嘗試formfield_for_foreignkey

class PlatformAdmin(admin.ModelAdmin): 
    def formfield_for_foreignkey(self, db_field, request, **kwargs): 
     if db_field.name == "default_version": 
      kwargs["queryset"] = Version.objects.filter(platform=self.instance.pk) 
     return super(PlatformAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) 
+0

但是我把XXXX放在了什麼位置? ,它不是字符串 – yossi 2012-03-08 15:24:31

+0

用動態值替換字符串。 – 2012-03-08 15:32:20

+0

動態值是我正在編輯的平臺,它是一個對象。我試着用自己。 – yossi 2012-03-08 15:37:31

0

這裏的問題已經變得扭曲。當你談論基於哪個平臺被選擇的版本選項適配時,你在談論AJAX。您只需創建一個接受平臺作爲參數的視圖並返回JSON格式的版本列表。

然後,您將一個手柄附加到平臺選擇框的onchange事件,該平臺選擇框將通過AJAX獲取該視圖,並使用JSON響應爲版本選擇框構造一組新的選項。用新的和完成的替換舊的選項。

在這個網站和網絡上有大量的例子。

+0

我說的是django管理員,如果我自己做視圖我不會有這個問題,順便說一句,即使沒有使用客戶端。 – yossi 2012-03-08 16:17:27

+0

我明白這一點,因爲他想限制Platform的change_view頁面上Version下拉菜單中的值。 – 2012-03-08 16:35:34

+0

問題是限制在Django中的版本下拉本身會導致問題,如果平臺有變化。如果您切換平臺,您仍然只能選擇舊平臺,更糟的是,即使您實現了AJAX來更新版本選項,它也不會進行驗證,因爲它僅限於舊平臺所擁有的版本。您*需要*將所有可能的版本列表保持不變,然後使用AJAX進行過濾以涵蓋所有使用場景。 @yossi:事實上,這是管理員對使用AJAX來改變選擇的能力沒有任何影響。 – 2012-03-08 16:55:20