【问题标题】:How to limit ForeignKey in django如何在 django 中限制 ForeignKey
【发布时间】:2012-03-26 01:06:00
【问题描述】:

我正在使用 django 1.2 我有两个模型。

编辑:我刚刚找到了一个更好的例子:

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 作为平台。
因此,当我在 wordpress 管理员中选择 default_version 下拉列表时,我希望它在下拉列表中仅显示我的版本“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')

但是我不知道要在 XXXX 中放置什么我尝试放置 self 但它没有用。
我也试过了

limit_choices_to={'platform.name':name}

我也没有工作。

在这个例子中,我希望能够选择一个最喜欢的孩子,但问题是管理员会给我所有的孩子供我选择,而不仅仅是我当前正在编辑的父母的孩子。

【问题讨论】:

  • limit_choices_to 不适用于动态值,请参阅stackoverflow.com/questions/1968596/… 我不确定这是否会对您的情况有所帮助,因为我猜这是在添加新平台而不是编辑?
  • 关于您的第二个示例,您希望为您的孩子设置一个 favorite 布尔字段,然后使用 unique_together
  • 但是我可以选择 2 个最喜欢的孩子,让他们有犯错的空间。

标签: django orm foreign-keys admin


【解决方案1】:

你可以试试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)

【讨论】:

  • 但是我在 XXXX 中放置了什么? ,它不是字符串
  • 用动态值替换字符串。
  • 动态值是我当前正在编辑的平台,它是一个对象。我尝试使用自我。
  • 认为是 self.instance.pk
【解决方案2】:

这里的问题已经歪曲了。当您谈论根据所选平台调整的版本选项时,您谈论的是 AJAX。您需要做的就是创建一个接受平台作为参数并返回 JSON 格式的版本列表的视图。

然后,您将处理程序附加到平台选择框的 onchange 事件,该事件将通过 AJAX 获取该视图并使用 JSON 响应为版本选择框构造一组新选项。用新选项替换旧选项并完成。

这个网站和整个网络上有很多例子。

【讨论】:

  • 我说的是 django 管理员,如果我自己完成视图,我就不会遇到这个问题,顺便说一句,即使不使用客户端。
  • 我理解为他想限制平台change_view页面上版本下拉菜单中的值。
  • 问题是限制 Django 本身的版本下拉菜单如果平台发生变化会导致问题。如果你切换平台,你仍然只有旧平台的选择,更糟糕的是,即使你实现了 AJAX 来更新版本选择,它也不会验证,因为它仅限于旧平台拥有的那些。您需要传递未更改的整个潜在版本列表,然后使用 AJAX 过滤以涵盖所有使用场景。 @yossi:这是在管理员中的事实与使用 AJAX 更改选择的能力零关系。
【解决方案3】:

我找到了基于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

【讨论】:

    猜你喜欢
    • 2010-09-28
    • 2018-04-21
    • 2014-06-30
    • 2022-01-20
    • 2020-07-01
    • 2011-08-11
    • 2015-02-15
    • 2016-12-29
    • 2016-03-28
    相关资源
    最近更新 更多