Register App myapp
1 2 3 4 5 6 7 8 9 10 11 | / / 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 ] |
myapp/views.py
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 | / / 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}) |
1 2 3 4 5 6 7 8 9 | / / devproject / urls.py from django.contrib import admin from django.urls import path, include urlpatterns = [ path( 'admin/' , admin.site.urls), path(' ', include(' myapp.urls')) ] |
1 2 3 4 5 6 7 8 9 10 11 12 | / / 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 ] |
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 | / / 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' ) |
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
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 | / / 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 |
1 2 3 4 5 6 7 8 9 10 | / / 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) |
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
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 | / / 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> $( "#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> |
1 2 3 4 5 | / / myapp / templates / city_dropdown_list_options.html <option value = ""> - - - - - - - - - < / option> { % for city in cities % } <option value = "{{ city.pk }}" >{{ city.name }}< / option> { % endfor % } |