修改过滤器水平搜索字段django

Modify filter horizontal search field django

我在 django 管理中使用 filter_horizontal。

有一个名为 Château Monlot 的葡萄园。当我尝试在搜索框中输入 Château 时,它就会出现。但是当我在搜索框中输入 Chateau(没有外来字符)时,它没有出现。

我想让它在我同时输入 Château 和 Chateau 时出现。我该怎么做?

此过滤器作为自定义 javascript 小部件实现,包含在 django.contrib.admin 中。

https://github.com/django/django/blob/e89f9571352f42c7752b351ba1e651485e5e7c51/django/contrib/admin/static/admin/js/SelectBox.js

我认为您可以通过对 SelectBox.filter 方法进行小的修改来获得您想要的结果。我们可以使用此技巧去除您搜索的所有节点中的重音符号和变音符号。

str.normalize('NFD').replace(/[\u0300-\u036f]/g, "");

来源:

例如,您可以将一些 javascript 添加到管理模板以更改表单,以覆盖原始搜索过滤器。

https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-admin-templates

像这样的东西可能会工作,扩展内置 admin/change_form.html

{% extends 'admin/change_form.html' %}    
{% block admin_change_form_document_ready %}
{{ block.super }}
<script>
if (window.SelectBox) {
  window.SelectBox.filter = function(id, text) {
    // lowercase and strip accents off search text
    const tokens = text
      .toLowerCase()
      .normalize('NFD')
      .replace(/[\u0300-\u036f]/g, "")
      .split(/\s+/);
    for (const node of SelectBox.cache[id]) {
      node.displayed = 1;
      // lowercase and strip accents off each node text in the filter list
      const node_text = node.text
        .toLowerCase()
        .normalize('NFD')
        .replace(/[\u0300-\u036f]/g, "");

      for (const token of tokens) {
        if (!node_text.includes(token)) {
          node.displayed = 0;
          break;
        }
      }
    }
    SelectBox.redisplay(id);
  }
}
</script>
{% endblock %}

还有其他方法可以将自定义 javascript 添加到管理站点,但是这个方法非常快速而且很脏。