How to get Interdependent dropdowns in django using Modelform and jquery?
You might need to use the following technologies:
- Custom Django Form Fields (Within the model form)
- ajax(to fetch the records)
- simplejson(to send a json response to ajax)
- jquery(to update the combo boxes on client side)
Let's have a look at an example(Not really tested this, just from the top of my mind):
Models.py
from django.db import modelsclass Campus(models.Model): name = models.CharField(max_length=100, choices=choices.CAMPUSES) def __unicode__(self): return u'%s' % self.nameclass School(models.Model): name = models.CharField(max_length=100) campus = models.ForeignKey(Campus) def __unicode__(self): return u'%s' % self.nameclass Centre(models.Model): name = models.CharField(max_length=100) school = models.ForeignKey(School) def __unicode__(self): return u'%s' % self.name
Forms.py
import modelsfrom django import formsclass CenterForm(forms.ModelForm): campus = forms.ModelChoiceField(queryset=models.Campus.objects.all()) school = forms.ModelChoiceField(queryset=models.School.objects.none()) # Need to populate this using jquery centre = forms.ModelChoiceField(queryset=models.Centre.objects.none()) # Need to populate this using jquery class Meta: model = models.Center fields = ('campus', 'school', 'centre')
Now, write a method in your views that returns a json object for schools under a campus and centres under a school:
Views.py
import modelsimport simplejsonfrom django.http import HttpResponsedef get_schools(request, campus_id): campus = models.Campus.objects.get(pk=campus_id) schools = models.School.objects.filter(campus=campus) school_dict = {} for school in schools: school_dict[school.id] = school.name return HttpResponse(simplejson.dumps(school_dict), mimetype="application/json")def get_centres(request, school_id): school = models.School.objects.get(pk=school_id) centres = models.Centre.objects.filter(school=school) centre_dict = {} for centre in centres: centre_dict[centre.id] = centre.name return HttpResponse(simplejson.dumps(centre_dict), mimetype="application/json")
Now write a ajax/jquery method to fetch the data and populate the select
elements in the HTML.
AJAX/jQuery
$(document).ready(function(){ $('select[name=campus]').change(function(){ campus_id = $(this).val(); request_url = '/get_schools/' + campus_id + '/'; $.ajax({ url: request_url, success: function(data){ $.each(data, function(index, text){ $('select[name=school]').append( $('<option></option>').val(index).html(text) ); }); } }); return false; })});
Rather than re-inventing the wheel, I would use Django Smart Selectsor Django Autocomplete Light
I haven't tried either yet but I'm about to use one or both of them in an upcoming project.