Как соединить несколько цепочек выпадающих элементов с помощью django-forms-dynamic

У меня есть форма с контрагентом, объектом и разделами, я соединил их друг с другом с помощью пакета django-forms-dynamic, но объект не соединен с разделами

Контрагент подключен к форме объекта, но секции не подключены к объекту, как это исправить?

Я предполагаю, что я ошибся с 2 функциями в forms.py: section_choices и initial_sections и они не связаны с объектами, но не знаю, как это исправить

forms.py


class WorkLogForm(DynamicFormMixin, forms.ModelForm):

    def object_choices(form):
        contractor_counter = form['contractor_counter'].value()
        object_query = ObjectList.objects.filter(contractor_guid__in=[contractor_counter])
        return object_query

    def initial_object(form):
        contractor_counter = form['contractor_counter'].value()
        object_query = ObjectList.objects.filter(contractor_guid__in=[contractor_counter])
        return object_query.first()

    def section_choices(form):
        contractor_object = form['contractor_object'].value()
        section_query = SectionList.objects.filter(object=contractor_object)
        return section_query

    def initial_sections(form):
        contractor_object = form['contractor_object'].value()
        section_query = SectionList.objects.filter(object=contractor_object)
        return section_query.first()

    contractor_counter = forms.ModelChoiceField(
        label='Контрагент',
        queryset=CounterParty.objects.none(),
        initial=CounterParty.objects.first(),
        empty_label='',
    )

    contractor_object = DynamicField(
        forms.ModelChoiceField,
        label='Объект',
        queryset=object_choices,
        initial=initial_object,
    )

    contractor_section = DynamicField(
        forms.ModelMultipleChoiceField,
        label='Раздел',
        queryset=section_choices,
        initial=initial_sections,
    )

views.py

@login_required
def create_work_log(request):
    if request.method == 'POST':
        form = WorkLogForm(request.POST, user=request.user)
        if form.is_valid():
            work_log = form.save(commit=False)
            work_log.author = request.user
            work_log = form.save()
            messages.success(request, 'Данные занесены успешно', {'work_log': work_log})
            return redirect('create_worklog')
        else:
            messages.error(request, 'Ошибка валидации')
            return redirect('create_worklog')
  
        form = WorkLogForm(user=request.user, initial=initial)

    return render(request, 'contractor/create_work_log.html', {'form': form})


def contractor_object(request):
    form = WorkLogForm(request.GET, user=request.user)
    return HttpResponse(form['contractor_object'])


def contractor_section(request):
    form = WorkLogForm(request.GET, user=request.user)
    return HttpResponse(form['contractor_section'])

Для соединения нескольких цепочек выпадающих элементов в Django с помощью HTMX, вы можете воспользоваться следующими шагами :

  1. Создайте представления Django, которые возвращают данные для каждого выпадающего списка на основе выбранного значения предыдущего выпадающего списка.

  2. Создайте HTML шаблоны для каждого выпадающего списка и включите в них HTMX атрибуты hx-post и hx-trigger для обработки взаимодействия между выпадающими списками.

  3. В HTML шаблонах привяжите атрибут hx-post выпадающего списка к URL соответствующего представления Django.

  4. В тех же шаблонах привяжите атрибут hx-trigger выпадающего списка к ID предыдущего выпадающего списка, чтобы он запускал запрос при изменении его значения.

  5. В представлениях Django используйте функцию render_to_response, чтобы вернуть HTML для следующего выпадающего списка.

Вот примерный фрагмент кода для представлений :

from django.shortcuts import render_to_response

def get_dropdown2_data(request):
    # Get the selected value of dropdown 1
    dropdown1_value = request.POST.get('dropdown1_value')
    # Generate data for dropdown 2 based on the selected value of dropdown 1
    dropdown2_data = [{'value': 1, 'text': 'Option 1'},
                      {'value': 2, 'text': 'Option 2'}]
    return render_to_response('dropdown2.html', {'dropdown2_data': dropdown2_data})

def get_dropdown3_data(request):
    # Get the selected value of dropdown 2
    dropdown2_value = request.POST.get('dropdown2_value')
    # Generate data for dropdown 3 based on the selected value of dropdown 2
    dropdown3_data = [{'value': 3, 'text': 'Option 3'},
                      {'value': 4, 'text': 'Option 4'}]
    return render_to_response('dropdown3.html', {'dropdown3_data': dropdown3_data})

Вот примерный фрагмент кода для шаблонов HTML :

<!-- dropdown1.html -->
<select id="dropdown1">
  <option value="">-- Select --</option>
  <option value="1">Option 1</option>
  <option value="2">Option 2</option>
</select>

<!-- dropdown2.html -->
<select id="dropdown2" hx-post="/get_dropdown2_data/" hx-trigger="#dropdown1">
  <option value="">-- Select --</option>
  {% for option in dropdown2_data %}
    <option value="{{ option.value }}">{{ option.text }}</option>
  {% endfor %}
</select>

<!-- dropdown3.html -->
<select id="dropdown3" hx-post="/get_dropdown3_data/" hx-trigger="#dropdown2">
  <option value="">-- Select --</option>
  {% for option in dropdown3_data %}
    <option value="{{ option.value }}">{{ option.text }}</option>
  {% endfor %}
</select>

Возможно, это не тот ответ, который вам нужен, но я использую HTMX для таких вещей. Вот ссылка на их пример для этого.

https://htmx.org/examples/value-select/

Существует также плагин пакета под названием Django-htmx.

Возможно, вам придется изучить HTMX, но это зрелая технология, довольно простая и надежная. Я не знаком с Django-forms-dynamic

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