(Django) Как сделать вариант «selected» действительным после изменения раскрывающегося списка внешнего ключа? - PullRequest
1 голос
/ 13 июля 2020

У меня есть модель, поля которой представляют собой дату и внешний ключ для текстового поля другой модели:

# 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'
    )

На странице Admin 'Добавить' для этой модели я добавил 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);
}

Если после выбора даты и просмотра выпадающего заголовка -down отфильтровать соответствующим образом, я выбираю один из отфильтрованных заголовков, я могу выбрать «Сохранить», и запись публикаций (дата и статья FK) будет успешно сохранена в базе данных.

Проблема I ' Я столкнулся с тем, что если я не выберу вручную статью из раскрывающегося списка после фильтрации по дате - например, если первый заголовок, отображаемый в новом, отфильтрованном раскрывающемся списке, - это тот, который я хочу, - и я попробую чтобы выбрать «Сохранить», страница перезагрузится с предложением «Исправьте ошибку ниже» и ошибкой над раскрывающимся заголовком «Выберите допустимый вариант. Этот вариант не является одним из доступных». Поведение уникально для первого варианта, показанного по умолчанию; это происходит, даже если я открываю раскрывающийся список и вручную нажимаю на этот параметр, и это происходит независимо от того, присвоил ли я ему атрибут «selected». Как я уже упоминал выше, если я открою раскрывающийся список и выберу любой другой вариант, страница будет работать нормально.

Я отследил сообщение об ошибке до класса ModelChoiceField() из django/forms/models.py в основном Django установка. Однако я не уверен, куда отсюда go. Я не только не хочу изменять файл в самом Django, я не знаю, как бы это сделать. Я не могу понять, какие изменения я могу внести в собственное приложение, чтобы сделать выбор статьи по умолчанию действительным.

Одно предположение, которое я могу сделать, заключается в том, что администратор запрограммирован на то, чтобы всегда обрабатывать первое значение при отбрасывании FK -down в качестве параметра-заполнителя, например "-----". Это правда, и есть ли способ отключить его с помощью настройки в моем приложении admin.py? Я попытался найти документацию по этому поводу, но не нашел ее.

В противном случае, как мне сделать выбор по умолчанию из раскрывающегося списка «Внешний ключ» «действительным выбором» после изменения содержимого раскрывающегося списка?

РЕДАКТИРОВАТЬ: Я решил, что для UX лучше оставить первый вариант как недействительный, который указывает, какая фильтрация была сделана, поэтому этот вопрос для моих целей спорный. Однако я думаю, что основной вопрос: «Всегда ли администратор Django обрабатывает первое значение в раскрывающемся списке FK как вариант заполнителя и есть ли способ его отключить?» это хороший вопрос, поэтому я оставляю его открытым.

1 Ответ

1 голос
/ 14 июля 2020

Ваша ошибка довольно тонкая: вы устанавливаете значение первой опции равным 0. Внешние ключи начинаются с 1 ... Таким образом, значение опции 0 никогда не может быть в выборе модели. И вы, вероятно, обнаружите, что выбранные статьи не соответствуют заголовкам (или только случайно).

Вы должны представить список из двух кортежей в свой ajax (или объекты с 'id' и 'title), а затем создайте opt.value = data.id.

...