Django - Country -> State-> City Dropdown list

22,480

Solution 1

Here is a very easy solution for anyone looking to implement a quick chained dropdown for django (or any website) for country --> state/province --> city, that does not require you to maintain a db.

https://geodata.solutions/

html

            <div class="card-body text-center">
                <select name="country" class="countries" id="countryId">
                    <option value="">Select Country</option>
                </select>
                <select name="state" class="states" id="stateId">
                    <option value="">Select State</option>
                </select>
                <select name="city" class="cities" id="cityId">
                    <option value="">Select City</option>
                </select>
            </div>

scripts

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
<script src="//geodata.solutions/includes/countrystatecity.js"></script>

its as simple as that.

if you are already loading jquery.min.js for ajax, no need to load it again. Just load the countrystatecity.js.

Solution 2

You can try also without ajax call:

<html>
<head> 
<title>Demo by kishan Radadiya</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
  <script type="text/javascript">
    $(document).ready(function(){
        // Countries
        var country_arr = new Array("Select Country","AUSTRALIA","INDIA","NEW ZEALAND","USA","UAE","MAURITIUS");

        $.each(country_arr, function (i, item) {
            $('#country').append($('<option>', {
                value: i,
                text : item,
            }, '</option>' ));
        });

        // States
        var s_a = new Array();
        s_a[0]="Select State";
        s_a[1]="Select State|QUEENSLAND|VICTORIA";
        s_a[2]="Select State|ANDHRAPRADESH|KARNATAKA|TAMILNADU|DELHI|GOA|W-BENGAL|GUJARAT|MADHYAPRADESH|MAHARASHTRA|RAJASTHAN";
        s_a[3]="Select State|AUCKLAND";
        s_a[4]="Select State|NEWJERSEY|ILLINOIS";
        s_a[5]="Select State|DUBAI";
        s_a[6]="Select State|MAURITIUS";

        // Cities
        var c_a = new Array();
        c_a['QUEENSLAND']="BRISBANE";
        c_a['VICTORIA']="MELBOURNE";
        c_a['ANDHRAPRADESH']="HYDERABAD";
        c_a['KARNATAKA']="BANGLORE";
        c_a['TAMILNADU']="CHENNAI";
        c_a['DELHI']="DELHI";
        c_a['GOA']="GOA";
        c_a['W-BENGAL']="KOLKATA";
        c_a['GUJARAT']="AHMEDABAD1|AHMEDABAD2|AHMEDABAD3|BARODA|BHAVNAGAR|MEHSANA|RAJKOT|SURAT|UNA";
        c_a['MADHYAPRADESH']="INDORE";
        c_a['MAHARASHTRA']="MUMBAI|PUNE";
        c_a['RAJASTHAN']="ABU";
        c_a['AUCKLAND']="AUCKLAND";
        c_a['NEWJERSEY']="EDISON";
        c_a['ILLINOIS']="CHICAGO";
        c_a['MAURITIUS']="MAURITIUS";
        c_a['DUBAI']="DUBAI";


        $('#country').change(function(){
            var c = $(this).val();
            var state_arr = s_a[c].split("|");
            $('#state').empty();
            $('#city').empty();
            if(c==0){
                $('#state').append($('<option>', {
                    value: '0',
                    text: 'Select State',
                }, '</option>'));
            }else {
                $.each(state_arr, function (i, item_state) {
                    $('#state').append($('<option>', {
                        value: item_state,
                        text: item_state,
                    }, '</option>'));
                });
            }
            $('#city').append($('<option>', {
                value: '0',
                text: 'Select City',
            }, '</option>'));
        });

        $('#state').change(function(){
            var s = $(this).val();
            if(s=='Select State'){
                $('#city').empty();
                $('#city').append($('<option>', {
                    value: '0',
                    text: 'Select City',
                }, '</option>'));
            }
            var city_arr = c_a[s].split("|");
            $('#city').empty();

            $.each(city_arr, function (j, item_city) {
                $('#city').append($('<option>', {
                    value: item_city,
                    text: item_city,
                }, '</option>'));
            });


        });
    });
</script>
</head>
<body>
<select name="country" id="country"></select> <br>
<select name="state" id="state"></select> <br>
<select name="city" id="city"></select>
</body>
</html>

Solution 3

Ive implemented the same thing successfully using this: http://elo80ka.wordpress.com/2009/10/14/jquery-plugin-chained-select-lists/

EDIT:
I dont have the code at hand, but adapting from the tutorial, first you create a views that returns the appropriate JSON:

def filter (request, model_class, field_name):
    try:
        kwargs = {smart_str(field_name): request.GET['q']}
    except KeyError:
        raise Http404
    qs = model_class.objects.filter(**kwargs).values('pk', 'name')
    response = HttpResponse(
        content=dumps(list(qs)),
        mimetype='application/json'
    )
    return response

EDIT 2: For the given schema, you would only need to change the urls.

In your urls:

urlpatterns = patterns('',
    url(r'^locations/filter/state-by-country/$', 'filter', {'model_class': State, 'field_name': 'country'},  name='state_filter')
    url(r'^locations/filter/city-by-state/$', 'filter', {'model_class': City, 'field_name': 'state'},  name='city_filter')
    ...
)

In your template, you would add the following (or you could create js files and add it to the form media, which is a better option):

$(function() {
  $('#id_state').chainedSelect({
    parent: '#id_country',
    url: 'locations/filter/find-by-country',
    value: 'id',
    label: 'name'
  });
});

$(function() {
  $('#id_city').chainedSelect({
    parent: '#id_state',
    url: 'locations/filter/find-by-state',
    value: 'id',
    label: 'name'
  });
});

If you could describe your table schema a little, i could help better.

Share:
22,480
Admin
Author by

Admin

Updated on July 09, 2022

Comments

  • Admin
    Admin almost 2 years

    I have been trying to create a 3 column drop-down list as Country, State, City.

    The list of state will be shown based on which country is selected. and the same thing happens to city depends on which State is selected.

    My database is as follow. If a country is selected, then states will show depending on country. Same thing happens to City

    A member will select his country,state, and city from an already existed Country, State, City databases

    from django.db import models
    
    
    class Member(models.Model):
    
           residing_country = models.CharField(max_length=50)
           residing_state = models.CharField(max_length=50)
           residing_city = models.CharField(max_length=50)
    
    class Country(models.Model):
    
             country= models.CharField(max_length=20)
    
    class State(models.Model):
    
             state=models.CharField(max_length=20)
             country = models.ForeignKey(Country)       
    
    class City(models.Model):
    
            city=models.CharField(max_length=20)
            state=models.ForeignKey(State)