Как соединить несколько цепочек выпадающих элементов с помощью 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, вы можете воспользоваться следующими шагами :
Создайте представления Django, которые возвращают данные для каждого выпадающего списка на основе выбранного значения предыдущего выпадающего списка.
Создайте HTML шаблоны для каждого выпадающего списка и включите в них HTMX атрибуты hx-post и hx-trigger для обработки взаимодействия между выпадающими списками.
В HTML шаблонах привяжите атрибут hx-post выпадающего списка к URL соответствующего представления Django.
В тех же шаблонах привяжите атрибут hx-trigger выпадающего списка к ID предыдущего выпадающего списка, чтобы он запускал запрос при изменении его значения.
В представлениях 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