o create the Django REST Framework (DRF) backend from scratch for the dependent dropdown functionality with Country, Division, and District models, follow these steps. This setup will provide the API endpoints needed for the React frontend to dynamically load the options for each dropdown based on the previous selection.
Step 1: Set Up Your Django Project
- Create a Django Project (if you haven’t already):
django-admin startproject myproject
cd myproject
BashCreate a Django App (for handling the models and API):
python manage.py startapp myapp
BashStep 2: Define Your Models
In your app’s models.py
, define the models for Country, Division, and District.
from django.db import models
class Country(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Division(models.Model):
country = models.ForeignKey(Country, related_name='divisions', on_delete=models.CASCADE)
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class District(models.Model):
division = models.ForeignKey(Division, related_name='districts', on_delete=models.CASCADE)
name = models.CharField(max_length=100)
def __str__(self):
return self.name
PythonStep 3: Migrate Your Models
Run the migrations to create the database schema.
python manage.py makemigrations
python manage.py migrate
BashStep 4: Create Serializers
In your app, create a serializers.py
file to define serializers for your models.
from rest_framework import serializers
from .models import Country, Division, District
class CountrySerializer(serializers.ModelSerializer):
class Meta:
model = Country
fields = ['id', 'name']
class DivisionSerializer(serializers.ModelSerializer):
class Meta:
model = Division
fields = ['id', 'name', 'country']
class DistrictSerializer(serializers.ModelSerializer):
class Meta:
model = District
fields = ['id', 'name', 'division']
PythonStep 5: Create Views
In your app’s views.py
, create views to list divisions and districts based on the selected country or division.
from rest_framework.generics import ListAPIView
from .models import Division, District
from .serializers import DivisionSerializer, DistrictSerializer
class DivisionListView(ListAPIView):
serializer_class = DivisionSerializer
def get_queryset(self):
country_id = self.kwargs['country_id']
return Division.objects.filter(country_id=country_id)
class DistrictListView(ListAPIView):
serializer_class = DistrictSerializer
def get_queryset(self):
division_id = self.kwargs['division_id']
return District.objects.filter(division_id=division_id)
PythonStep 6: Configure URLs
In your app’s urls.py
, set up the URL patterns for the API endpoints.
from django.urls import path
from .views import DivisionListView, DistrictListView
urlpatterns = [
path('api/divisions/<int:country_id>/', DivisionListView.as_view(), name='divisions-list'),
path('api/districts/<int:division_id>/', DistrictListView.as_view(), name='districts-list'),
]
PythonStep 7: Enable Django REST Framework and CORS
- Install Django REST Framework and CORS headers:
pip install djangorestframework django-cors-headers
BashAdd to INSTALLED_APPS in settings.py
:
INSTALLED_APPS = [
...
'rest_framework',
'corsheaders',
...
]
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
...
]
# Use the following for development purposes
CORS_ALLOW_ALL_ORIGINS = True
PythonStep 8: Run Your Server
python manage.py runserver
BashCreate a React Component
This component will include dropdowns for countries, divisions, and districts. It will fetch the divisions when a country is selected, and fetch the districts when a division is selected.
import React, { useState, useEffect } from 'react';
function AddressSelector() {
const [countries, setCountries] = useState([]);
const [divisions, setDivisions] = useState([]);
const [districts, setDistricts] = useState([]);
const [selectedCountry, setSelectedCountry] = useState('');
const [selectedDivision, setSelectedDivision] = useState('');
useEffect(() => {
// Fetch countries on component mount
fetch('/api/countries/') // Adjust the endpoint as necessary
.then(response => response.json())
.then(data => setCountries(data));
}, []);
useEffect(() => {
if (selectedCountry) {
fetch(`/api/divisions/${selectedCountry}/`)
.then(response => response.json())
.then(data => setDivisions(data));
}
}, [selectedCountry]);
useEffect(() => {
if (selectedDivision) {
fetch(`/api/districts/${selectedDivision}/`)
.then(response => response.json())
.then(data => setDistricts(data));
}
}, [selectedDivision]);
const handleCountryChange = (event) => {
setSelectedCountry(event.target.value);
setDivisions([]); // Reset divisions when country changes
setDistricts([]); // Reset districts as well
};
const handleDivisionChange = (event) => {
setSelectedDivision(event.target.value);
};
return (
<div>
<select value={selectedCountry} onChange={handleCountryChange}>
<option value="">Select a Country</option>
{countries.map(country => (
<option key={country.id} value={country.id}>{country.name}</option>
))}
</select>
<select value={selectedDivision} onChange={handleDivisionChange} disabled={!selectedCountry}>
<option value="">Select a Division</option>
{divisions.map(division => (
<option key={division.id} value={division.id}>{division.name}</option>
))}
</select>
<select disabled={!selectedDivision}>
<option value="">Select a District</option>
{districts.map(district => (
<option key={district.id} value={district.id}>{district.name}</option>
))}
</select>
</div>
);
}
export default AddressSelector;
Bash