'Populate/filter one <select> with another <select>
I have a form to create projects in my app. In this form the user must select a client in a and then a farm in another . How do I when selecting a client, the next only offers options from farms that are from the selected customer? I believe it's impossible to do this with just Django, am I right?
simplified models.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'
Solution 1:[1]
I found an answer that needs little jquery and uses logic in forms.py, it was exactly what I was looking for (since I only understand the basics of Java). Here is the updated code:
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 %}
I FOUNDED THIS LOGIC IN: GIT
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
