Я хочу создать цепочку из нескольких вариантов выбора. У меня есть рабочий код для цепочек выпадающих списков ниже. Я хочу иметь возможность выбрать более одной опции на каждом уровне, и чтобы следующий уровень возвращал все записи для каждого из выбранных значений. Как я могу это сделать? (мой код не очень DRY, поэтому оцените все заметки, но это второстепенно)
models.py
class Nace_Level_1(models.Model):
code = models.CharField(max_length=1)
name = models.CharField(max_length=200)
short_name = models.CharField(max_length=100)
notes = models.TextField()
def __str__(self):
return self.short_name
class Nace_Level_2(models.Model):
parent = models.ForeignKey(Nace_Level_1, on_delete=models.CASCADE)
code = models.CharField(max_length=2)
name = models.CharField(max_length=200)
short_name = models.CharField(max_length=100)
notes = models.TextField()
def __str__(self):
return self.short_name
class Nace_Level_3(models.Model):
parent = models.ForeignKey(Nace_Level_2, on_delete=models.CASCADE)
code = models.CharField(max_length=4)
name = models.CharField(max_length=200)
short_name = models.CharField(max_length=100)
notes = models.TextField()
def __str__(self):
return self.short_name
class Nace_Level_4(models.Model):
parent = models.ForeignKey(Nace_Level_3, on_delete=models.CASCADE)
code = models.CharField(max_length=5)
name = models.CharField(max_length=200)
short_name = models.CharField(max_length=100)
notes = models.TextField()
def __str__(self):
return self.short_name
class Nace_Level_5(models.Model):
parent = models.ForeignKey(Nace_Level_4, on_delete=models.CASCADE, blank=True, null=True)
level_3 = models.ForeignKey(Nace_Level_3, on_delete=models.CASCADE, blank=True, null=True)
level_2 = models.ForeignKey(Nace_Level_2, on_delete=models.CASCADE, blank=True, null=True)
level_1 = models.ForeignKey(Nace_Level_1, on_delete=models.CASCADE, blank=True, null=True)
code = models.CharField(max_length=6)
name = models.CharField(max_length=200)
short_name = models.CharField(max_length=100)
notes = models.TextField()
def __str__(self):
return self.short_name
forms.py
class NaceForm(forms.ModelForm):
level_5 = forms.ChoiceField(label='', choices=Nace_Level_5.objects.none())
class Meta:
model = Nace_Level_5
fields = ('level_1','level_2','level_3','parent','level_5')
labels = {'level_1': (""),
'level_2': (""),
'level_3': (""),
'parent' : (""),}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['level_1'].queryset = Nace_Level_1.objects.all()
self.fields['level_2'].queryset = Nace_Level_2.objects.none()
self.fields['level_3'].queryset = Nace_Level_3.objects.none()
self.fields['parent'].queryset = Nace_Level_4.objects.none()
self.fields['level_1'].widget.attrs={'data-nace-url':'/ajax/load-level-2/'}
self.fields['level_2'].widget.attrs={'data-nace-url':'/ajax/load-level-3/'}
self.fields['level_3'].widget.attrs={'data-nace-url':'/ajax/load-level-4/'}
self.fields['parent'].widget.attrs={'data-nace-url':'/ajax/load-level-5/'}
urls.py
urlpatterns = [
path("industries/", views.NaceCreateView.as_view(), name="industries"),
path('ajax/load-level-2/', views.load_level_2, name="ajax_load_level_2"),
path('ajax/load-level-3/', views.load_level_3, name="ajax_load_level_3"),
path('ajax/load-level-4/', views.load_level_4, name="ajax_load_level_4"),
path('ajax/load-level-5/', views.load_level_5, name="ajax_load_level_5"),
]
views.py
class NaceCreateView(CreateView):
template_name = 'main/industries.html'
model = Nace_Level_5
form_class = NaceForm
def load_level_2(request):
level_1_id = request.GET.get('level_1')
level_2 = Nace_Level_2.objects.filter(parent=level_1_id)
return render(request, 'main/level_dropdown.html', {'levels': level_2})
def load_level_3(request):
level_2_id = request.GET.get('level_2')
level_3 = Nace_Level_3.objects.filter(parent=level_2_id)
return render(request, 'main/level_dropdown.html', {'levels': level_3})
def load_level_4(request):
level_3_id = request.GET.get('level_3')
level_4 = Nace_Level_4.objects.filter(parent=level_3_id)
return render(request, 'main/level_dropdown.html', {'levels': level_4})
def load_level_5(request):
level_4_id = request.GET.get('parent')
level_5 = Nace_Level_5.objects.filter(parent=level_4_id)
return render(request, 'main/level_dropdown.html', {'levels': level_5})
шаблоны / главная / отрасли. html
<div class='row'>
<div class='col'>
<form method="post" id="naceForm" novalidate>
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
</form>
</div>
</div>
<script>
$("#id_level_1").change(function () {
var url = $("#id_level_1").attr("data-nace-url");
var level_1_id = $(this).val();
$.ajax({
url: url,
data: {
'level_1': level_1_id
},
success: function (data) {
$("#id_level_2").html(data);
}
});
});
$("#id_level_2").change(function () {
var url = $("#id_level_2").attr("data-nace-url");
var level_2_id = $(this).val();
$.ajax({
url: url,
data: {
'level_2': level_2_id
},
success: function (data) {
$("#id_level_3").html(data);
}
});
});
$("#id_level_3").change(function () {
var url = $("#id_level_3").attr("data-nace-url");
var level_3_id = $(this).val();
$.ajax({
url: url,
data: {
'level_3': level_3_id
},
success: function (data) {
$("#id_parent").html(data);
}
});
});
$("#id_parent").change(function () {
var url = $("#id_parent").attr("data-nace-url");
var parent_id = $(this).val();
$.ajax({
url: url,
data: {
'parent': parent_id
},
success: function (data) {
$("#id_level_5").html(data);
}
});
});
</script>
шаблоны / главная / level_dropdown. html
<option value="">---------</option>
{% for level in levels %}
<option value="{{ level.id }}">{{ level.short_name }}</option>
{% endfor %}