给定具有 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 个实例(标题:a1-3),当通过管理员Article
编辑现有实例时,该字段默认由一个 html(多个)选择框表示,该框提供所有文章的列表 ( )。用户应该只看到并能够选择除自身以外的实例,例如在编辑a1 时,可用于选择 = a2、a3。Article
related_articles
Article.objects.all()
Article
Article
related_articles
我目前可以看到 3 种可能的方法来做到这一点,按偏好递减的顺序排列;
- 提供一种方法来设置查询集,在管理表单字段中提供可用选项
related_articles
(通过排除查询过滤器,例如Article.objects.filter(~Q(id__iexact=self.id))
,从用户可以查看和选择的相关文章列表中排除正在编辑的当前实例。创建/设置要使用的查询集可以在__init__
自定义的构造函数 () 中发生Article ModelForm
,或者通过某种动态limit_choices_to Model
选项发生。这需要一种方法来获取正在编辑的实例以用于过滤。 - 覆盖or类的
save_model
函数以在保存实例之前检查并从中删除自身。这仍然意味着管理员用户可以查看和选择所有文章,包括正在编辑的实例(对于现有文章)。Article Model
ModelAdmin
related_articles
- 当需要在管理员之外使用时过滤掉自我引用,例如模板。
理想的解决方案 (1) 目前可以通过管理员外部的自定义模型表单来完成,因为可以将正在编辑的实例的过滤查询集变量传递给模型表单构造函数。问题是,您能否获得Article
实例,即在创建表单之前正在编辑“自我”以执行相同的操作。
可能是我以错误的方式解决这个问题,但是如果您允许将 FKF / MTMF 定义为同一模型,那么应该有一种方法让管理员 -做正确的事情- 并阻止用户通过以下方式选择自己在可用选项列表中排除它。
注意:现在可以执行解决方案 2 和 3,并提供解决方案以尝试避免将这些作为答案,理想情况下,我希望得到解决方案 1 的答案。