给定一个带有外键的 ForeignKeyField (FKF) 或 ManyToManyField (MTMF) 字段的模型,我如何防止在 Django Admin (admin) 中进行自我(递归)选择。

简而言之,应该可以防止管理中模型实例的自我(递归)选择。这适用于编辑模型的现有实例,而不是创建新实例。

例如,对新闻应用中的一篇文章采用以下模型;

class Article(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField()
    related_articles = models.ManyToManyField('self')

如果有 3 个 Article 实例(标题:a1-3),当通过 admin 编辑现有的 Article 实例时,related_articles 字段默认由一个 html(多个)选择框表示,它提供了一个 html(多个)x22513143 篇文章列表(x2213143)。用户应该只能看到并能够选择 Article.objects.all() 实例以外的实例,例如编辑 Article a1 时,Article 可供选择 = a2, a3。

我目前可以看到 3 种可能的方法来做到这一点,按照优先级递减的顺序;
  • 提供一种设置查询集的方法,在管理表单字段中为 related_articles 提供可用选项(通过排除查询过滤器,例如 related_articles 以从用户可以查看/选择的相关文章列表中排除正在编辑的当前实例。该查询集来使用的设置自定义Article.objects.filter(~Q(id__iexact=self.id)),或构造函数(__init__)内可能发生,通过某种动态Article ModelForm选项的。这就需要一种方式来攫取实例正在编辑使用了过滤。
  • 覆盖 limit_choices_to Modelsave_model 类的 Article Model 函数的 ModelAdmin 函数,以便在保存实例 0x23134312 之前检查并从 0x2313431 中删除自身这仍然意味着管理员用户可以查看和选择所有文章,包括正在编辑的实例(对于现有文章)。
  • 当需要在管理员之外使用时过滤掉自引用,例如模板。

  • 理想的解决方案 (1) 目前可以通过 admin 之外的自定义模型表单来完成,因为可以将正在编辑的实例的过滤查询集变量传递给模型表单构造函数。问题是,您能否获得 related_articles 实例,即在创建表单以执行相同操作之前正在编辑“自我”。

    可能是我以错误的方式处理这个问题,但是如果您允许将 FKF/MTMF 定义为相同的模型,那么应该有一种方法让管理员 - 做正确的事情 - 并防止用户选择自己将其排除在可用选项列表中。

    注意: 现在可以使用解决方案 2 和 3,并且提供这些是为了尽量避免将这些作为答案,理想情况下我想得到解决方案 1 的答案。

    最佳答案

    您可以在管理中使用自定义 ModelForm(通过设置 the "form" attribute of your ModelAdmin subclass )。因此,您在管理员中以与在其他任何地方相同的方式进行操作。

    关于django - 如何防止 Django Admin 中 FK/MTM 字段的自(递归)选择,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/869856/

    10-13 07:34