Register App myapp
//devproject/settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'myapp', #add myapp ]Creating View
myapp/views.py
//myapp/views.py from django.shortcuts import render, redirect, get_object_or_404 from .forms import MemberCreationForm from .models import Member, City def create_view(request): form = MemberCreationForm() if request.method == 'POST': form = MemberCreationForm(request.POST) if form.is_valid(): form.save() return redirect('add') return render(request, 'home.html', {'form': form}) def update_view(request, pk): member = get_object_or_404(Member, pk=pk) form = MemberCreationForm(instance=member) if request.method == 'POST': form = MemberCreationForm(request.POST, instance=member) if form.is_valid(): form.save() return redirect('change', pk=pk) return render(request, 'home.html', {'form': form}) # AJAX def load_cities(request): country_id = request.GET.get('country_id') cities = City.objects.filter(country_id=country_id).all() return render(request, 'city_dropdown_list_options.html', {'cities': cities})devproject/urls.py
//devproject/urls.py from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('myapp.urls')) ]myapp/urls.py
//myapp/urls.py from django.urls import path from . import views urlpatterns = [ path('member/add/', views.create_view, name='add'), path('member/<int:pk>/', views.update_view, name='change'), path('member/ajax/load-cities/', views.load_cities, name='ajax_load_cities'), # AJAX ]myapp/forms.py
//myapp/forms.py from django import forms from myapp.models import Member, City class MemberCreationForm(forms.ModelForm): class Meta: model = Member fields = '__all__' widgets = { 'name': forms.TextInput(attrs={ 'class': 'form-control' }), 'email': forms.EmailInput(attrs={ 'class': 'form-control' }), 'country': forms.Select(attrs={ 'class': 'form-select' }), 'city': forms.Select(attrs={ 'class': 'form-select' }), } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['city'].queryset = City.objects.none() if 'country' in self.data: try: country_id = int(self.data.get('country')) self.fields['city'].queryset = City.objects.filter(country_id=country_id).order_by('name') except (ValueError, TypeError): pass # invalid input from the client; ignore and fallback to empty City queryset elif self.instance.pk: self.fields['city'].queryset = self.instance.country.city_set.order_by('name')Make Migrations
Run the commands below to make migrations:
python manage.py makemigrations
python manage.py migrate
C:\django\devproject>python manage.py makemigrations
C:\django\devproject>python manage.py migrate
myapp/models.py
//myapp/models.py from django.db import models class Country(models.Model): name = models.CharField(max_length=40) def __str__(self): return self.name class City(models.Model): country = models.ForeignKey(Country, on_delete=models.CASCADE) name = models.CharField(max_length=40) def __str__(self): return self.name class Member(models.Model): name = models.CharField(max_length=124) email = models.CharField(max_length=125) country = models.ForeignKey(Country, on_delete=models.SET_NULL, blank=True, null=True) city = models.ForeignKey(City, on_delete=models.SET_NULL, blank=True, null=True) def __str__(self): return self.namemyapp/admin.py
//myapp/admin.py from django.contrib import admin # Register your models here. from myapp.models import City, Country, Member admin.site.register(City) admin.site.register(Country) admin.site.register(Member)Bootstrap 5
https://getbootstrap.com/docs/5.0/getting-started/introduction/
https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css
Jquery
https://jquery.com/download/
CDN : jsDelivr CDN
https://www.jsdelivr.com/package/npm/jquery
https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js
myapp/templates/home.html
//myapp/templates/home.html <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Dependent Dropdown in Django</title> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"> </head> <body> <div class="container"> <p><h1>Python Django Dependent Chained Dropdown List - Dynamic Dependent Select Box using jQuery Ajax</h1></p> <div class="card"> <div class="card-header"> Member Form </div> <div class="card-body"> <form method="post" id="MemberForm" data-cities-url="{% url 'ajax_load_cities' %}" class="form-horizontal" role="form"> {% csrf_token %} {{ form.as_p }} <input type="submit" value="Submit" class="btn btn-info"> </form> </div> </div> </div> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script> $("#id_country").change(function () { const url = $("#MemberForm").attr("data-cities-url"); // get the url of the `load_cities` view const countryId = $(this).val(); // get the selected country ID from the HTML input $.ajax({ // initialize an AJAX request url: url, // set the url of the request (= /members/ajax/load-cities/ ) data: { 'country_id': countryId // GET parameters }, success: function (data) { $("#id_city").html(data); } }); }); </script> </body> </html>myapp/templates/city_dropdown_list_options.html
//myapp/templates/city_dropdown_list_options.html <option value="">---------</option> {% for city in cities %} <option value="{{ city.pk }}">{{ city.name }}</option> {% endfor %}Run : C:\django\devsite>python manage.py runserver