Come implementare due dropdown dipendenti l’una dall’altra in Django e jQuery
16:40PythonStefano
Ciao a tutti.
Con l’articolo di oggi vorrei mostrare come implementare due dropdown dipendenti l’una dall’altra usando Django e jQuery.
Supponiamo di avere una relazione 1-N tra marca di automobile e modello: nella prima dropdown vogliamo mostrare la lista delle marche; una volta selezionata una marca mostreremo nella seconda dropdown la lista dei modelli filtrati per quella marca.
Ipotizziamo di avere i modelli definiti così:
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) |
Iniziamo a definire il templatetag da includere nei nostri template:
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} |
Come possiamo vedere, il tag richiede un template html di supporto. Vediamo come è definito:
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> |
Possiamo notare che non appena viene selezionato una marca, viene invocata una chiamata Ajax a questa url:
/brand/”selected_brand_code”/all_json_models
Dobbiamo definire dunque un’apposita view per poter intercettare questa url:
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") |
e in urls.py:
1 2 3 | #urls.py ... (r'^brand/(?P<brand>[-\w]+)/all_json_models/$', 'all_json_models'), |
Infine, il metodo javascript myAwesomeFunctionToCallWhenAModelIsSelected(); verrà scatenato una volta selezionato il nostro modello.

















Great Post! i just need it!
I think that there is small bug in views.py:
Put VehicleBrand.objects.get() instead of VehicleBrand.get() and VehicleModel.objects.all().filter() instead if VehicleModel.all().filter()
Thanks Mario.
I’ve fixed the code
Appena usato proprio in un portale per auto usate,
complimenti per il tuo lavoro
dimenticavo…penso tu abbia dimenticato una } nello script
This is just what I need.
Anyway do you have a sample project files, I really new with Django. Thanks.
Simply awesome !
Very helpful. Thanks.
Great doc ,Not works when Jquery transform applied..