1. Home
  2. Docs
  3. Django Rest Framework
  4. dependent dropdowns

dependent dropdowns

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

  1. Create a Django Project (if you haven’t already):
django-admin startproject myproject
cd myproject
Bash

Create a Django App (for handling the models and API):

python manage.py startapp myapp
Bash

Step 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
Python

Step 3: Migrate Your Models

Run the migrations to create the database schema.

python manage.py makemigrations
python manage.py migrate
Bash

Step 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']
Python

Step 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)
Python

Step 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'),
]
Python

Step 7: Enable Django REST Framework and CORS

  1. Install Django REST Framework and CORS headers:
pip install djangorestframework django-cors-headers
Bash

Add 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
Python

Step 8: Run Your Server

python manage.py runserver
Bash

Create 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

How can we help?