Blog › Python

How to implement two dropdowns dependent on each other using Django and jQuery

Hello everyone.

With today’s article I want to show how to implement two dropdowns dependent on each other using Django and jQuery.

Suppose we have a 1-N relationship between car brands and car models: we want to show the list of brands in the first dropdown; then once you have selected a brand, the second dropdown will show a list of filtered models for that brand.

Suppose we have our models defined as follows:

1
2
3
4
5
6
7
8
9

#models.py
class VehicleBrand(models.Model):
description = models.CharField(max_length=100)
code = models.SlugField(primary_key=True)

class VehicleModel(models.Model):
description = models.CharField(max_length=100)
code = models.SlugField(primary_key=True)
brand = models.ForeignKey(VehicleBrand)

Let’s write a templatetag that will be included in our templates:

1
2
3
4
5
6
7
8
9
10
11

#templatetags.py
from models import VehicleBrand

from django import template

register = template.Library()

@register.inclusion_tag("brand_model_select.html")
def brand_model_select():
brand_list = VehicleBrand.objects.all()
return {'brand_list' : brand_list}

As you can see, the templatetag requires a support html template, defined as follow:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

<!-- brand_model_select.html -->
<form action="" method="get" accept-charset="utf-8">
<select name="brand" id="brand">
<option value="Z">Select a brand</option>
{% for brand in brand_list %}
<option value="{{ brand.code}}">{{ brand.description }}</option>
{% endfor %}
</select>
<select name="model" id="model" disabled="true">
<option>Select a model</option>
</select>
</form>
<script>
$(document).ready(
function() {
$("select#brand").change(function() {
if ($(this).val() == 'Z') {
$("select#model").html("<option>Select a model</option>");
$("select#model").attr('disabled', true);
}
else {
var url = "/brand/" + $(this).val() + "/all_json_models";
var brand = $(this).val();
$.getJSON(url, function(models) {
var options = '<option value="Z">Select a model</option>';
for (var i = 0; i < models.length; i++) {
options += '<option value="' + models[i].pk + '">' + models[i].fields['description'] + '</option>';
}
$("select#model").html(options);
$("select#model option:first").attr('selected', 'selected');
$("select#model").attr('disabled', false);
});
}
});


$("select#model").change(function(vent) {
if ($(this).val() == -1) {
return;
}
myAwesomeFunctionToCallWhenAModelIsSelected();
});
});
}

</script>

Please note that once a brand is selected, the following url will be invoked via Ajax request:
/brand/”selected_brand_code”/all_json_models

then we need to define a view to handle this request:

1
2
3
4
5
6

#views.py
def all_json_models(request, brand):
current_brand = VehicleBrand.objects.get(code=brand)
models = VehicleModel.objects.all().filter(brand=current_brand)
json_models = serializers.serialize("json", models)
return HttpResponse(json_models, mimetype="application/javascript")

and in urls.py:

1
2
3

#urls.py
...
(r'^brand/(?P<brand>[-\w]+)/all_json_models/

Finally, the javascript method myAwesomeFunctionToCallWhenAModelIsSelected() will be invoked when a model will be selected.

, 'all_json_models'),
{replace25}

Find out where AI can save your company time.

One hour with our team: we map your processes, pick 2-3 concrete use cases and tell you what is worth doing first. No strings attached.

Book a free AI assessment
Subsidised finance

Incentives and grants for your software or AI project.

With specialised partners we check which incentives your project can access and prepare the paperwork and the financing plan.

  • Hyper-depreciation for 4.0 and 5.0 assets
  • National and regional grants
  • Financing plan
Book a free AI assessment