Django.fun

Modify filter horizontal search field django

I'm using filter_horizontal in django admin.

enter image description here

There is a vineyard called Château Monlot. When I try to type Château on the search box, it will appear. But when I type Chateau (without foreign char) on the search box, it doesn't appear.

I want to make it appear when I type both Château and Chateau. How can I do that?

This filter is implemented as a custom javascript widget that is included with django.contrib.admin.

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

I think you could get what you want by monkeypatching a small change to the SelectBox.filter method. We can use this trick to strip accents and diacritics in all the nodes you search through.

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

Source: https://stackoverflow.com/a/37511463/1977847

For example you can add some javascript to a admin template for change form, to override the original search filter.

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

Something like this might work, extending the builtin 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) {
    const tokens = text.toLowerCase().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 %}

There are other ways to add custom javascript to the admin site, but this one is very quick and dirty.

Tutorials

Современный Python: начинаем проект с pyenv и poetry

Настройка проекта Python — виртуальные среды и управление пакетами

Использование requests в Python — тайм-ауты, повторы, хуки

Понимание декораторов в Python

ProcessPoolExecutor в Python: полное руководство

map() против submit() с ProcessPoolExecutor в Python

Понимание атрибутов, словарей и слотов в Python

Полное руководство по slice в Python

Выпуск Django 4.0

Безопасное развертывание приложения Django с помощью Gunicorn, Nginx и HTTPS

Автоматический повтор невыполненных задач Celery

Django REST Framework и Elasticsearch

Докеризация Django с помощью Postgres, Gunicorn и Nginx

Асинхронные задачи с Django и Celery

Релизы безопасности Django: 3.2.4, 3.1.12 и 2.2.24

Выпуски исправлений ошибок Django: 3.2.3, 3.1.11 и 2.2.23

Эффективное использование сериализаторов Django REST Framework

Выпуски безопасности Django: 3.2.2, 3.1.10 и 2.2.22

Выпущенные релизы безопасности Django: 3.2.1, 3.1.9 и 2.2.21

Обработка периодических задач в Django с помощью Celery и Docker

View all tutorials →