(Django)如何在更改外键下拉列表后使“选定”选项有效?

Posted

技术标签:

【中文标题】(Django)如何在更改外键下拉列表后使“选定”选项有效?【英文标题】:(Django) How do I make the 'selected' option valid after altering a foreign key drop-down? 【发布时间】:2020-11-02 15:28:36 【问题描述】:

我有一个模型,其字段是日期和另一个模型文本字段的外键:

# models.py
class Publications(models.Model):
    """A class for daily article publications"""

    date = models.DateField(
        help_text="date for this article to be published"
    )
    headline = models.ForeignKey(
        Articles,
        help_text='The article to be published, represented by its headline'
    )

在该模型的管理员“添加”页面上,我添加了 javascript,因此当我从日历选择器小部件中为 date 选择日期时,文章 FK 的下拉选择器会自动限制为当天准备发表的文章的子集。这是通过清除下拉选择器,然后用对后端视图的 AJAX 调用的结果重新填充它来完成的:

// Javascript for Publications "Add" admin page
// Grab the Article <select> element
let artSelect = document.getElementById("id_headline");

// Clear it
artSelect.innerhtml = '';

// Fill it with new <option> elements from 'data', a list of Article
// headlines retrieved via AJAX
for (var i=0; i<data.length; i++) 
    var opt = document.createElement('option');
    opt.value = i;
    opt.innerHTML = data[i];
    // If it's the first option, make it 'selected'
    if (i == 0) 
        opt.setAttribute("selected", "");
    
    artSelect.appendChild(opt);

如果在选择日期并查看标题下拉菜单被相应过滤后,我选择了一组过滤后的标题,我可以选择“保存”,并且出版物条目(日期和文章 FK)将保存到数据库成功。

我遇到的问题是,如果我没有在按日期过滤后从下拉菜单中手动选择一篇文章——例如,如果新的过滤下拉菜单中显示的第一个标题是我想要 - 我尝试选择保存,页面重新加载并提示“请更正下面的错误”,并且标题下拉列表中出现错误“选择一个有效的选择。该选择不是可用的选择之一。 "该行为对于第一个选项是唯一的,默认情况下显示;即使我打开下拉菜单并手动单击该选项也会发生这种情况,并且无论我是否给它“选定”属性都会发生这种情况。正如我上面提到的,如果我打开下拉菜单并选择任何其他选项,页面就可以正常工作。

我已将错误消息跟踪到主 Django 安装中的 django/forms/models.pyModelChoiceField() 类。但是,我不确定从这里去哪里。我不仅不想更改 Django 本身中的文件,而且我不知道该怎么做。我不知道我可以在自己的应用中进行哪些更改以使默认的文章选择有效。

我可以做出的一个猜测是,管理员被编程为始终将 FK 下拉列表中的第一个值视为占位符选项,例如“-----”。这是真的吗,有没有办法通过我的应用程序admin.py 中的设置来禁用它?我尝试查找有关此的文档,但找不到任何文档。

否则,如何在更改下拉列表内容后将外键下拉列表的默认选择设为“有效选择”?

编辑:我已经决定将第一个选项保留为指示已完成过滤的无效选项更好的用户体验,所以这个问题对我来说没有实际意义。但是,我认为“Django Admin 是否总是将 FK 下拉列表中的第一个值视为占位符选项,有没有办法禁用它”的潜在问题?是一个很好的问题,所以我不回答这个问题。

【问题讨论】:

【参考方案1】:

您的错误非常微妙:您将第一个选项的值设置为 0。外键从 1 开始......因此选项值 0 永远不会出现在模型选项中。而且您可能会发现所选文章与标题不对应(或只是偶然)。

您应该向您的 ajax(或带有 'id' 和 'title 的对象)提供一个 2 元组列表,然后创建 opt.value = data.id。

【讨论】:

我已经通过测试确认这是正确的。还好我没有回答这个问题!

以上是关于(Django)如何在更改外键下拉列表后使“选定”选项有效?的主要内容,如果未能解决你的问题,请参考以下文章

外键 id 无法加载到 Django 模板的下拉列表中

如何从 Django 的下拉列表中从用户的选定选项中进行查询

如何在 ReactJS 中更改单选按钮时重置选定的下拉列表

如何使用 JqGrid 更改 select2 下拉列表的选定值?

Django外键下拉

更改下拉列表选定值