Заполнение/фильтрация одного <select> другим <select>
У меня есть форма для создания проектов в моем приложении. В этой форме пользователь должен выбрать клиента в одной форме, а затем ферму в другой. Как сделать так, чтобы при выборе клиента, в следующем предлагались только варианты из ферм, которые принадлежат выбранному клиенту? Я считаю, что это невозможно сделать с помощью только Django, я прав?
упрощенные модели.py
class Project(models.Model):
farm = models.ManyToManyField(Farm, related_name='farm_name',verbose_name='Propriedade beneficiada')
client = models.ForeignKey(Clients, on_delete=models.CASCADE, related_name='project_client',default=None,null=True, verbose_name='Cliente')
class Farm(models.Model):
client = models.ForeignKey(Clients, on_delete=models.CASCADE, related_name='client', null=True, default=None)
name = models.CharField(max_length=100, verbose_name='Nome')
forms.py
class NewProjectForm(ModelForm):
class Meta:
model = Project
fields = ['owner','farm','warranty','modal','harvest_year','culture','value','final_date']
def __init__(self, *args,**kwargs):
super(NewProjectForm, self).__init__(*args,**kwargs)
self.fields['value'].required = False
self.fields['final_date'].required = False
self.fields['owner'].queryset = Owner.objects.all().order_by('name')
farm_query = Farm.objects.all().order_by('name')
self.fields['farm'].queryset = farm_query
self.fields['warranty'].queryset = farm_query
self.fields['final_date'].widget.attrs['data-mask'] = "00/00/0000"
for field_name, field in self.fields.items():
field.widget.attrs['class'] = 'form-control'
Я нашел ответ, который не требует много jquery и использует логику в forms.py, это было именно то, что я искал (поскольку я понимаю только основы Java). Вот обновленный код:
forms.py
class NewProjectForm(ModelForm):
class Meta:
model = Project
fields = ['client','owner','farm','warranty','modal','harvest_year','culture','value','final_date']
def __init__(self, *args,**kwargs):
super(NewProjectForm, self).__init__(*args,**kwargs)
self.fields['value'].required = False
self.fields['final_date'].required = False
self.fields['owner'].queryset = Owner.objects.all().order_by('name')
self.fields['final_date'].widget.attrs['data-mask'] = "00/00/0000"
self.fields['farm'].queryset = Farm.objects.none()
if 'client' in self.data:
try:
client_id = int(self.data.get('client'))
self.fields['farm'].queryset = Farm.objects.filter(client_id=client_id).order_by('name')
except (ValueError, TypeError):
pass
elif self.instance.pk:
self.fields['farm'].queryset = self.instance.client.farm_set.order_by('name')
for field_name, field in self.fields.items():
field.widget.attrs['class'] = 'form-control'
url.py
(...)
path('new/',views.project_new,name='project_new'),
path('ajax/load-farms/',views.load_farms,name='ajax_load_farms'), #AJAX
views.py
@login_required
def project_new(request):
clients = Clients.objects.all().order_by('name')
farms = Farm.objects.all().order_by('name')
form = NewProjectForm()
return render(request,'project_new.html',{'clients':clients,
'farms':farms,
'form':form})
def load_farms(request):
client_id = request.GET.get('client_id')
farms = Farm.objects.filter(client_id=client_id)
return render(request, 'farm_dropdown_list_options.html', {'farms':farms})
farm_dropdown_list_options.html
<option value="">-----</option>
{% for farm in farms %}
<option value="{{ farm.pk }}">{{ farm.name }}</option>
{% endfor %}
project_new.html
{% extends 'base.html' %}
{% block title %}
<title>Novo Projeto</title>
{% endblock %}
{% block content %}
<form name="form" id="form" method="POST" data-farm-url="{% url 'ajax_load_farms' %}">
{% csrf_token %}
{{ form }}
<input type="submit" value="Enviar">
</form>
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script>
$('#id_client').change(function()
{
const url = $('#form').attr('data-farm-url');
const clientId = $(this).val();
$.ajax({
url: url,
data: {
'client_id': clientId
},
success: function(data){
$("#id_farm").html(data);
console.log('opa');
}
});
});
</script>
{% endblock %}
Я ОСНОВАЛ ЭТУ ЛОГИКУ В: GIT