Форма мастера Django и партиции htmx
Я создаю форму мастера django с несколькими формами, однако в одной из форм у меня есть поле с небольшим списком секторов, и когда пользователь выбирает сектор, я запускаю функцию, которая получает подсектора этого сектора. Проблема в том, что когда я тестирую форму в отдельном html-шаблоне, она работает нормально, но когда я использую ее в своей форме мастера, она не обновляет ui, хотя в консоли я вижу, что запрос был успешным.
#urls.py
from django.urls import path # type: ignore
from django.utils.translation import gettext_lazy as _ # type: ignore
from core import views
app_name = 'core'
urlpatterns = [
path('', views.OnboardingSessionWizardView.as_view(views.FORMS), name='start'),
path('sub-sectors/', views.get_subsectors, name='get-sub-sectors'),
path('get-started/', views.OnboardingSessionWizardView.as_view(views.FORMS), name='get-started'),
]
вот мой view.py:
from core.forms import *
from formtools.wizard.views import SessionWizardView # type: ignore
from django.http import HttpResponse, JsonResponse, HttpRequest # type: ignore
from django.utils.translation import gettext_lazy as _ # type: ignore
from django.shortcuts import render,get_object_or_404 # type: ignore
from django.core.serializers import serialize # type: ignore
from core.models import *
from core.forms import *
# Create your views here.
FORMS = [("contact", EntryInformationForm),
("information", PersonalInformationForm),
("business", BusinessActivityForm),
("address", BusinessAddressForm),
]
TEMPLATES = {
"contact": "forms/core/_entry_information.html",
"information": "forms/core/_personal_information.html",
"business": "forms/core/_business_activity.html",
"address": "forms/core/_address.html"
}
def get_subsectors(request):
subsectors = []
sector_id = request.GET.get('sector')
try:
sector = get_object_or_404(Sector, name = sector_id)
subsectors = sector.subsectors.all()
except:
subsectors = []
subsectors_data = serialize('json', subsectors)
return render(request, 'partials/subsector_options.html', {'subsectors': subsectors})
class OnboardingSessionWizardView(SessionWizardView):
# form_list = [
# (_('CONTACT'),UserEntryInformationForm),
# (_('INFORMATIONS PERSONNELLES'),UserPersonalInformationForm),
# (_('VOTRE ACTIVITÉ '),UserBusinessActivityInformationForm), # Business Information
# ]
# template_name = 'onboarding.html'
form_list = FORMS
def get_template_names(self):
print(f"Current step: {self.steps.current}")
return [TEMPLATES[self.steps.current]]
def done(self, form_list, **kwargs):
return HttpResponse('Onboarding process done')
def get_context_data(self, form, **kwargs):
context = super().get_context_data(form=form, **kwargs)
context['countries'] = Country.objects.all()
return context
а это мой шаблон деловой активности, где я использую эту форму:
Это мой частичный html-шаблон подсекторов:
{% if subsectors %}
<div class="relative mt-1.5">
<label for="subsectors">Secteur d'activité</label>
<input
type="text"
name="subsectors"
placeholder="Secteur d'activité"
list="subsectors-list"
class="w-full rounded-lg border-gray-300 pe-10 text-gray-700 sm:text-sm [&::-webkit-calendar-picker-indicator]:opacity-0"
autocomplete="off"
value="{{subsectors.first}}"
/>
<datalist id="subsectors-list">
{% for subsector in subsectors %}
<option value="{{ subsector.name }}" data-id="{{ subsector.id }}">{{ subsector.name }}</option>
{% endfor %}
</datalist>
</div>
{% endif %}
и, наконец, вот мой файл forms.py:
class BusinessActivityForm(forms.ModelForm):
activity_type = forms.ChoiceField(
widget=forms.RadioSelect(),
choices=BusinessActivity.BUSINESS_CHOICES,
label=_("Avez-vous déjà exercé une activité non-salariée ?"),
initial=BusinessActivity.BUSINESS_CHOICES[0][0]
)
class Meta:
model = BusinessActivity
fields = ['sector','when_to_start','commercial_name','activity_type']
widgets = {
'sector': forms.Select(attrs={
'placeholder': _("Domaine d'activité "),
'label': _("Domaine d'activité "),
}
),
'when_to_start': forms.DateInput(attrs={'placeholder': _('DD-MM-YYYY'), 'type': 'date'}),
'commercial_name': forms.TextInput(attrs={'placeholder': _('Nom comercial (optionnel)')}),
}
Я попробовал все, но не могу заставить его работать. есть ли лучший подход, поскольку список подкатегорий довольно большой, и моя главная цель сделать это таким образом, чтобы дать пользователю возможность вводить текст и иметь законные предложения автозаполнения
Моя техника отладки заключается в просмотре идентификаторов: Я бы проверил идентификаторы различных элементов на отрисованной странице, чтобы убедиться, что они соответствуют вашим намерениям. SessionWizard префиксирует имена и идентификаторы элементов с именем формы. В то же время при использовании включений партиций проверьте, что объекты, от которых вы ожидаете значений, действительно имеют эти значения - я обычно просто печатаю их в HTML, чтобы это было очевидно!
Кроме того, я заметил, что hx-target установлен как
hx-target="#sub-sectors-list"
Но я не смог сразу увидеть в коде целевой id у какого-либо элемента. Может быть, это subsectors-list?
В то же время, если вы используете инструмент для верстки форм, такой как Crispy, он также может изменить структуру id (шаблоны crispy добавляют id к таким элементам, как select)
Поэтому лучше всего отрендерить страницу и проверить, что ожидаемые вами идентификаторы находятся на странице и соответствуют hx-целям и т.д.