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.name
myapp/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
