HTMX Django не активируется на полях формы
У меня есть форма с 3 вариантами выбора, когда пользователь выбирает первый, я обновил второй с помощью htmx, когда пользователь выбирает второй, я хотел бы обновить третий таким же образом. Однако третий не инициализирует htmx-запрос.
Вот моя форма django:
purchased_by = forms.ModelChoiceField(
label="Empresa compradora",
queryset=OurCompany.objects.filter(definecat=2).order_by('name'),
widget=forms.Select(attrs={'class': 'form-control',
'hx-get': reverse_lazy('compras:oc_update_local'),
'hx-trigger': 'change',
'hx-target': '#div_local',
'hx-swap': 'outerHTML'}),
)
delivery_location = forms.ModelChoiceField(
label="Local de Entrega/Obra",
queryset=Empreendimento.objects.all().order_by('name'),
widget=forms.Select(attrs={'class': 'form-control',
'hx-get': reverse_lazy('compras:oc_update_cc'),
'hx-trigger': 'change',
'hx-target': '#div_cc',
'hx-swap': 'outerHTML'}),
)
Вот мои взгляды:
def oc_update_local(request):
company = request.GET.get('purchased_by')
empresa = OurCompany.objects.get(pk=company)
if empresa.definecat == 1:
if empresa.name[:5] == "Cabiu":
company = OurCompany.objects.get(name='Cabiunas Inc')
empreendimentos = Empreendimento.objects.filter(
company=company).order_by('name')
elif empresa.name[:5] == "Coque":
company = OurCompany.objects.get(
name='Coqueiral Agropecuaria Matriz')
empreendimentos = Empreendimento.objects.filter(
company=company).order_by('name')
else:
empreendimentos = Empreendimento.objects.filter(
company=company).order_by('name')
return render(request, "compras/partials/oc_update_local.html", {"empreendimentos": empreendimentos})
def oc_update_cc(request):
local = request.GET.get('delivery_location')
ccs = CentroCusto.objects.filter(imovel=local).order_by('name')
return render(request, "compras/partials/oc_update_cc.html", {"ccs": ccs})
А это мой html-шаблон:
<div class="form-row">
<div class="form-group col-3">
{{ form.purchased_by | as_crispy_field }}
</div>
<div class="form-group col-4" id="div_local">
{{ form.delivery_location | as_crispy_field }}
</div>
<div class="form-group col-4" id="div_cc">
{{ form.cc |as_crispy_field }}
</div>
</div>
И у меня есть частичное обновление для каждого обновления, но второе никогда не срабатывает.
Спасибо за помощь
происходит только один htmx-запрос в браузере
Проблема, с которой вы столкнулись, скорее всего, связана с тем, что второй элемент <select>
(delivery_location
) не срабатывает должным образом на обновление третьего элемента <select>
(cc
). Это может происходить потому, что hx-get
для третьего селекта настроен на срабатывание по второму селекту (delivery_location
), но нет механизма для передачи обновленного значения из второго селекта в третий.
Решение:
- Передайте значение
delivery_location
в представлениеoc_update_cc
: Чтобы HTMX правильно запускал обновление третьего<select>
, необходимо убедиться, что значение из второго<select>
отправляется на сервер, когда он запускает запрос для третьего<select>
. Для этого необходимо динамически включить значениеdelivery_location
в HTMX-запрос. - Добавьте
hx-ge
t для третьего select: Вам нужно будет динамически обновлять третий<select>
на основе значения второго.
Вот возможное решение:
<div class="form-row">
<div class="form-group col-3">
{{ form.purchased_by | as_crispy_field }}
</div>
<div class="form-group col-4" id="div_local">
{{ form.delivery_location | as_crispy_field }}
</div>
<div class="form-group col-4" id="div_cc">
{{ form.cc |as_crispy_field }}
</div>
</div>
Теперь измените поле delivery_location
, чтобы вызвать HTMX-запрос для третьего поля:
delivery_location = forms.ModelChoiceField(
label="Local de Entrega/Obra",
queryset=Empreendimento.objects.all().order_by('name'),
widget=forms.Select(attrs={
'class': 'form-control',
'hx-get': reverse_lazy('compras:oc_update_cc'),
'hx-trigger': 'change',
'hx-target': '#div_cc',
'hx-swap': 'outerHTML',
'hx-vals': '{ "delivery_location": this.value }', # Dynamically send value of selected option
}),
)
В файле views.py
def oc_update_cc(request):
local = request.GET.get('delivery_location') # This should now contain the value of the selected 'delivery_location'
ccs = CentroCusto.objects.filter(imovel=local).order_by('name')
return render(request, "compras/partials/oc_update_cc.html", {"ccs": ccs})
Такой подход должен гарантировать, что выбор опции во втором <select>
вызовет HTMX-запрос на обновление третьего <select>
, и в запрос будет корректно включено выбранное значение второго поля. Большое спасибо! Желаю вам прекрасного остатка дня! 😊