2012-03-08 55 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