Skip to content

sangwani-coder/zambia_geo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Zambia Geo

A Python package containing Zambian provinces and cities data.

Features

  • List all Zambian provinces
  • Get cities for each province
  • Search for cities
  • Validate province and city names

Install in Development Mode Locally

  1. Create a virtual environment:

     python -m venv venv
     source venv/bin/activate  # On Windows: venv\Scripts\activate
    
  2. Install the package in development mode:

     git clone https://github.com/sangwani-coder/zambia_geo.git
     cd zambia_geo
     pip install -e .
    
  3. Run Tests

     python -m pytest tests/
    

Alternative Installation Methods

Installation in a Project - Force Install

pip install --force-reinstall git+https://github.com/sangwani-coder/zambia_geo.git

Download the ZIP and install

wget https://github.com/sangwani-coder/zambia_geo/archive/main.zip
pip install main.zip

Now you can import and use the package in your Python code:

from zambia_geo import get_all_provinces, get_province_cities
# Get all provinces
provinces = get_all_provinces()
for province in provinces:
    print(province.name, province.capital)

# Get cities in a province
cities = get_province_cities("Lusaka")
for city in cities:
    print(city.name, city.population)

Usage in Django

To use zambia_geo package in Django model choice fields, you'll need to create choices tuples from the package's data. Here's how you can implement this:

Example Django Model Usage

from django.db import models
from zambia_geo.utils import get_province_choices, get_city_choices

class UserProfile(models.Model):
    # Province field
    province = models.CharField(
        max_length=50,
        choices=get_province_choices(),
        blank=True,
        null=True
    )
    
    # City field that depends on province
    city = models.CharField(
        max_length=50,
        choices=[],
        blank=True,
        null=True
    )
    
    class Meta:
        verbose_name = "User Profile"
        verbose_name_plural = "User Profiles"
    
    def __str__(self):
        return f"{self.province} - {self.city}"

Dynamic City Choices Based on Province (Forms)

To make the city choices dynamic based on the selected province, you'll need to use JavaScript or Django's form facilities:

Step 1: Using Django Forms with JavaScript:

# forms.py
from django import forms
from .models import UserProfile
from zambia_geo.utils import get_province_choices, get_city_choices

class UserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ['province', 'city']
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['province'].choices = [('', 'Select Province')] + get_province_choices()
        self.fields['city'].choices = [('', 'Select City')]
        
        # Set initial city choices if province is already selected
        if self.instance and self.instance.province:
            self.fields['city'].choices = [('', 'Select City')] + get_city_choices(self.instance.province)

Step 2: Create a View to handle Ajax Request

# views.py
from django.http import JsonResponse
from zambia_geo.utils import get_city_choices

def load_cities(request):
    province = request.GET.get('province')
    if province:
        cities = get_city_choices(province)
        return JsonResponse({'cities': cities})
    return JsonResponse({'cities': []})

Add URL Patten

# urls.py
from django.urls import path
from .views import load_cities

urlpatterns = [
    path('load-cities/', load_cities, name='load_cities'),
    # other paths...
]

In your template

# admin.py
<!-- Include jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

<form method="post" id="profileForm">
    {% csrf_token %}
    
    <div class="form-group">
        {{ form.province.label_tag }}
        {{ form.province }}
    </div>
    
    <div class="form-group">
        {{ form.city.label_tag }}
        {{ form.city }}
    </div>
    
    <button type="submit" class="btn btn-primary">Save</button>
</form>

<script>
$(document).ready(function() {
    // When province changes
    $('#id_province').change(function() {
        var provinceId = $(this).val();
        var url = "{% url 'load_cities' %}";
        
        // Clear and disable city dropdown
        $('#id_city').html('<option value="">Select City</option>');
        
        if (provinceId) {
            // Fetch cities for selected province
            $.ajax({
                url: url,
                data: {
                    'province': provinceId
                },
                success: function(data) {
                    // Populate city dropdown
                    var options = '<option value="">Select City</option>';
                    $.each(data.cities, function(index, city) {
                        options += '<option value="' + city[0] + '">' + city[1] + '</option>';
                    });
                    $('#id_city').html(options);
                }
            });
        }
    });
});
</script>

Update your view to Handle your Form

# views.py
from django.shortcuts import render, redirect
from .forms import UserProfileForm

def profile_view(request):
    if request.method == 'POST':
        form = UserProfileForm(request.POST, instance=request.user.profile)
        if form.is_valid():
            form.save()
            return redirect('success_url')
    else:
        form = UserProfileForm(instance=request.user.profile)
    
    return render(request, 'profile_form.html', {'form': form})

Usage in Flask

  flask_zambia_app/
  ├── app.py
  ├── templates/
  │   └── index.html
  └── requirements.txt

Flask Application Code:

  # app.py
  from flask import Flask, render_template, request, jsonify
  from zambia_geo.utils import get_province_choices, get_city_choices
  
  app = Flask(__name__)
  
  @app.route('/', methods=['GET', 'POST'])
  def index():
      if request.method == 'POST':
          # Process form submission
          province = request.form.get('province')
          city = request.form.get('city')
          return f"Selected: {province} Province, {city} City"
      
      # GET request - show the form
      provinces = get_province_choices()
      return render_template('index.html', provinces=provinces)
  
  @app.route('/get_cities')
  def get_cities():
      province = request.args.get('province')
      if province:
          cities = get_city_choices(province)
          return jsonify({'cities': cities})
      return jsonify({'cities': []})
  
  if __name__ == '__main__':
      app.run(debug=True)

Template File:

  <!-- index.html -->
  <!DOCTYPE html>
  <html>
  <head>
      <title>Zambia Provinces and Cities</title>
      <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
      <style>
          .form-group { margin-bottom: 15px; }
          select { padding: 8px; width: 300px; }
      </style>
  </head>
  <body>
      <h1>Select Location in Zambia</h1>
      
      <form method="POST">
          <div class="form-group">
              <label for="province">Province:</label>
              <select id="province" name="province" required>
                  <option value="">Select Province</option>
                  {% for code, name in provinces %}
                      <option value="{{ code }}">{{ name }}</option>
                  {% endfor %}
              </select>
          </div>
          
          <div class="form-group">
              <label for="city">City:</label>
              <select id="city" name="city" required disabled>
                  <option value="">Select City (choose province first)</option>
              </select>
          </div>
          
          <button type="submit">Submit</button>
      </form>
  
      <script>
      $(document).ready(function() {
          $('#province').change(function() {
              var province = $(this).val();
              var $citySelect = $('#city');
              
              $citySelect.empty().prop('disabled', true);
              
              if (province) {
                  $citySelect.append('<option value="">Loading cities...</option>');
                  
                  $.getJSON('/get_cities', {province: province}, function(data) {
                      $citySelect.empty().append('<option value="">Select City</option>');
                      
                      $.each(data.cities, function(index, city) {
                          $citySelect.append(
                              $('<option>', {
                                  value: city[0],
                                  text: city[1]
                              })
                          );
                      });
                      
                      $citySelect.prop('disabled', false);
                  });
              }
          });
      });
      </script>
  </body>
  </html>

About

A Python package containing Zambian provinces and cities data.

Resources

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published

Languages