Django : Динамическая установка выпадающих опций на основе выбора других выпадающих опций в Django Model Forms

Это распространенный сценарий во фронтенде, когда мы хотим установить опции выпадающего списка относительно другого выбора в другом выпадающем списке, но не получаем решения в админ-формах django Сценарий django model:

class CompanyEmployee():
    """
    An Emailed Report
    """
    company = models.ForeignKey(Company,
                              on_delete=models.CASCADE,
                               )
    employee = models.ManyToManyField(Employee,
                                   blank=True,
                                   verbose_name='Employes',)

    class Meta:
        unique_together = (
            ('company', 'name'),
        )

так в CompanyEmailAdminForm компания находится в list_filter, а сотрудник в filter_horizontal, то есть компания является выпадающим списком, а сотрудник фильтром с множественным выбором.

Набор запросов для виджета сотрудника

     if instance.pk:
            self.fields['employee'].queryset =Employee.objects.filter(company=instance.company)
        else:
            self.fields['employee'].queryset =Employee.objects.all()

Компания и сотрудник имеют связь. Поэтому из компании я могу получить связанные записи о сотрудниках.

Проблема возникает в форме добавления, где у меня нет сохраненного экземпляра.

Мое требование: когда я выбираю компанию, скажем 'ABC', я должен получить только записи, связанные с 'ABC' в фильтре сотрудников.

Если при onChange я могу получить значение обратно в форму, я могу повторно оценить набор запросов сотрудников. С помощью django.JQuery значения в разделе сотрудников не сохраняются постоянно.

Начал кодить на Django несколько недель назад.

Я не очень хорошо понял некоторые из ваших данных, но я поделюсь с вами тем, как я сделал зависимые выпадающие окна с помощью Django простым способом. Я также использовал javascript.

Вам необходимо добавить следующее в код вашего шаблона:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

Затем необходимо добавить в шаблон две формы выбора, по одной для каждого поля. Одна будет для родительского поля, другая - для дочернего. Структура может быть такой:

  • Родительский выбор
<select id="field1" name="field1" class="form-control">
    <option hidden selected value="" id="nullfield1">Select field 1</option>
    <option value="A">A</option>
    <option value="B">B</option>
    <option value="C">C</option>
</select>
  • Child select
<select id="field2" name="field2" class="form-control">
    <option hidden selected value="" id="nullfield2">Select field 2</option>
    <option value="1" parent="A">1</option>
    <option value="2" parent="A">2</option>
    <option value="3" parent="B">3</option>
    <option value="4" parent="B">4</option>
    <option value="5" parent="C">5</option>
    <option value="6" parent="C">6</option>
</select>

Затем вы добавляете в ваш шаблон следующий код Javascript:

<script>
    var document = window.document;
    $(document).ready(function(){

        var $field1var=$("#field1");
        var $field2var=$("#field2");

        var $field2options=$field2var.find('option');

        $field2var.html($field2options.filter('[value=""]'));

        $field1var.on('change',function(){
            $field2var.html($field2options.filter('[parent="'+this.value+'"],[value=""]'));
            $('#field2 option[value=""]').prop('selected', true);

        });
    });
</script>

После этого параметры второго поля будут изменяться по мере изменения первого поля.

Посмотрите структуру и скопируйте ее для своей работы.

Я оставлю вам простой и завершенный шаблон, который вы можете визуализировать, чтобы попробовать его.

<html>
    <body>
        <div class="container">
            <div class="row">
                <select id="field1" name="field1" class="form-control">
                    <option hidden selected value="" id="nullfield1">Select field 1</option>
                    <option value="A">A</option>
                    <option value="B">B</option>
                    <option value="C">C</option>
                </select>
                <select id="field2" name="field2" class="form-control">
                    <option hidden selected value="" id="nullfield2">Select field 2</option>
                    <option value="1" parent="A">1</option>
                    <option value="2" parent="A">2</option>
                    <option value="3" parent="B">3</option>
                    <option value="4" parent="B">4</option>
                    <option value="5" parent="C">5</option>
                    <option value="6" parent="C">6</option>
                </select>
            </div>
        </div>
    </body>
</html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
    var document = window.document;
    $(document).ready(function(){
        var $field1var=$("#field1");
        var $field2var=$("#field2");
        var $field2options=$field2var.find('option');
        $field2var.html($field2options.filter('[value=""]'));
        $field1var.on('change',function(){
            $field2var.html($field2options.filter('[parent="'+this.value+'"],[value=""]'));
            $('#field2 option[value=""]').prop('selected', true);
        });
    });
</script>

Надеюсь, это то, что вам было нужно!!!

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