Django-Autocomplete-Light: Взаимное исключение выделения нескольких полей

Я использую Django Autocomplete Light (DAL) с большим эффектом. Он прекрасно работает и работает уже много лет на одном из моих сайтов. Недавно я захотел улучшить небольшой аспект нашей реализации, а именно предотвратить множественный выбор одного и того же значения в группе виджетов DAL.

Конкретно мы построили динамическую Django форму, с помощью которой можно отправить список игроков. В таблице есть строка шаблона, и каждый раз, когда вы добавляете игрока, она копирует строку шаблона, корректирует id виджетов в копии по мере необходимости и вставляет ее в DOM (как новую строку).

Все это работает просто замечательно. Виджеты DAL отображаются в элементе select с именем и id в форме model-n-field, которые обработчик POST прекрасно валидирует, и все хорошо.

Эти виджеты DAL выглядят в общем виде:

<select id="id_model-n-field" name="model-n-field" class="ModelChoiceField select2-hidden-accessible" data-autocomplete-light-language="en" data-autocomplete-light-url="/autocomplete/model/field" data-autocomplete-light-function="select2" data-select2-id="id_model-n-field" aria-hidden="true">
    <option value="" selected="" data-select2-id="13">---------</option>
</select>
<span class="select2 select2-container select2-container--bootstrap select2-container--below select2-container--focus select2-container--open" dir="ltr" data-select2-id="12" style="width: 426.906px;">
    <span class="selection">
        <span class="select2-selection select2-selection--single ModelChoiceField" role="combobox" aria-haspopup="true" aria-expanded="true" tabindex="2" aria-disabled="false" aria-labelledby="select2-id_model-n-field-container" aria-owns="select2-id_model-n-field-results">
            <span class="select2-selection__rendered" id="select2-id_model-n-field-container" role="textbox" aria-readonly="true">
                <span class="select2-selection__placeholder">
            </span>
        </span>
        <span class="select2-selection__arrow" role="presentation">
            <b role="presentation"></b>
        </span>
    </span>
</span>

Мне еще предстоит выяснить, как, где и для чего обработчик клика для обратного вызова AJAX прикреплен к этому HTML, но я уверен, что он находится во внутренностях элемента Select2 и управляется различными атрибутами класса select2 (с некоторым onload запущенным JS, прикрепляющим обработчики событий к элементам определенных классов select2).

Я вижу в коде на стороне сервера, в обработчике AJAX, что приходит через запрос. В частности, модель и поле доступны через объект запроса в обработчике.

Теперь, поскольку это динамическая форма, с этим шаблоном, повторяющимся по запросу на стороне клиента, с именами и идентификаторами охватывающих select элементов, получающих число n для отражения строки, на форме может быть несколько таких элементов.

Все это работает замечательно и работает уже много лет. Замечательная динамическая форма и механизм ввода формы.

Есть только одна маленькая идиосинкразия, которая также была в списке дел на протяжении многих лет, чтобы ее устранить, и на которую я обратил внимание сейчас. Можно выбрать одного и того же игрока в двух или более рядах, но не легальной подачей. В настоящее время это обнаруживается на стороне сервера и возвращается как ошибка валидации в Django.

Тогда передо мной стоит задача настроить виджет(ы) DAL так, чтобы обратный вызов AJAX (на data-autocomplete-light-url) получал список выбранных значений во всех других виджетах DAL группы и мог отфильтровать их из возвращаемого списка.

Если этого не сделать, то можно найти способ подключиться к JS, обрабатывающему результаты, который (имея доступ к DOM) может удалить элементы, выбранные в других DAL-виджетах группы. Это, конечно, менее желательно, чем передача выбранных значений в AJAX URL (как GET параметры) по той простой причине, что DAL виджет запрашивает их по одной странице за раз, и фильтрация в идеале выполняется до пагинации, а не после (возможно, что существующий выбор более или менее уничтожит страницу, например, в последнем случае)

Мне интересно, существует ли парадигма, с помощью которой виджеты DAL могут быть настроены на отправку дополнительной информации вместе с AJAX запросом, в настраиваемой манере (информация предоставляется, скажем, функцией JS). В своих чтениях и блужданиях я пока не нашел такого варианта, но прежде чем я попытаюсь его разработать, я хотел бы воспользоваться коллективной мудростью сообщества.

Воображаемая парадигма:

  1. При создании виджета autocomplete.ModelSelect2 в бэкенде на Python, называя JS функцию, которая будет вызываться для предоставления GET параметров AJAX запроса.
  2. Написание функции в JS на стороне клиента, которая считывает все виджеты DAL в одной группе и возвращает GET-параметры, идентифицирующие выбранные элементы в других виджетах DAL.

Это кажется такой простой парадигмой, остается вопрос, реализована ли она или нет и доступна ли нам.

Вернуться на верх