A reusable Django app for hierarchical address fields.
Project description
Django Hierarchical Address
A reusable Django app for hierarchical, international address fields with full REST API and Django admin support. Easily add continent, country, state/province, city, county, and detailed address fields to any model, with automatic filtering and dynamic dropdowns.
Features
- Hierarchical address models: Continent, Country, State/Province, City, County, Address
- International standards (ISO codes, etc.)
- Full Django REST Framework API with filtering and nested serialization
- Django admin integration with dynamic, chained selects (custom JavaScript)
- Highly customizable and extensible
- Use as relations (ForeignKey/OneToOne) or as embedded models/fields
- Ready for pip installation
Installation
-
Install the package (in your Django project):
pip install django-hierarchical-address # OR for local development: pip install -e /path/to/your/django-hierarchical-address
-
Add to
INSTALLED_APPSin yoursettings.py:INSTALLED_APPS = [ # ... 'rest_framework', 'django_filters', 'django_places', ]
-
Include the API URLs in your main
urls.py:from django.urls import path, include urlpatterns = [ # ... path('api/places/', include('django_places.urls')), ]
-
(Optional, for admin dynamic selects) Ensure static files are collected:
python manage.py collectstatic
Usage
1. Migrate the database:
python manage.py makemigrations django_places
python manage.py migrate
2. Register address fields in your models:
You can use the provided Address model as a ForeignKey or OneToOneField in your own models:
from django.db import models
from django_places.models import Address
class MyModel(models.Model):
name = models.CharField(max_length=100)
address = models.OneToOneField(Address, on_delete=models.CASCADE)
3. Use as Embedded Models/Fields or Custom Fields
You can now use the address models as embedded fields (not just relations) using custom fields. For example:
from django.db import models
from django_places.models import CountryField, StateProvinceField, CityField, CountyField
class MyCustomAddress(models.Model):
country = CountryField(null=True, blank=True, help_text="Country of origin")
state_province = StateProvinceField(null=True, blank=True)
city = CityField(null=True, blank=True)
county = CountyField(null=True, blank=True)
address_line = models.CharField(max_length=255, blank=True)
zip_code = models.CharField(max_length=20, blank=True)
# ... add your own fields ...
All standard Django field options (null, blank, default, help_text, etc.) are supported for these custom fields.
Or, you can use the provided models as abstract base classes to create your own address model:
from django_places.models import Address
class MyAbstractAddress(Address):
extra_field = models.CharField(max_length=100)
class Meta:
abstract = True
4. Django Admin
- All address models are registered in the admin.
- The Address admin form features dynamic dropdowns for country, state/province, city, and county.
- When you select a parent (e.g., country), the child dropdown (e.g., state/province) updates instantly.
Admin Form Example:
5. REST API
- All address models are available via REST endpoints:
/api/places/continents//api/places/countries//api/places/states-provinces//api/places/cities//api/places/counties//api/places/addresses/
- Filtering is supported via query parameters, e.g.:
/api/places/countries/?continent=1/api/places/states-provinces/?country=1/api/places/cities/?state_province=1/api/places/counties/?city=1
- Nested serialization: Each object includes its parent objects for easy data consumption.
- When creating/updating an Address, only valid child options are accepted (e.g., only cities in the selected state).
API Example: Create Address
POST /api/places/addresses/
{
"continent_id": 1,
"country_id": 2,
"state_province_id": 5,
"city_id": 10,
"county_id": 20,
"address_line": "123 Main St",
"zip_code": "12345",
"location": "51.5074,-0.1278",
"details": "Near the park"
}
API Example: Get Address
{
"id": 1,
"continent": {"id": 1, "name": "Europe", "code": "EU"},
"country": {"id": 2, "name": "United Kingdom", "code": "GBR", "continent": 1},
"state_province": {"id": 5, "name": "England", "code": "ENG", "country": 2},
"city": {"id": 10, "name": "London", "state_province": 5},
"county": {"id": 20, "name": "Camden", "city": 10},
"address_line": "123 Main St",
"zip_code": "12345",
"location": "51.5074,-0.1278",
"details": "Near the park"
}
API Example: Filter Cities by State/Province
GET /api/places/cities/?state_province=5
Customization
- Extend models: You can subclass or swap out any model for your own needs.
- Override serializers or viewsets: For custom API behavior, override the provided serializers or viewsets in your project.
- Admin customization: The admin form uses custom JavaScript for chained selects. You can further customize this by editing
django_places/static/django_places/address_chained.js. - Use as fields or embedded models: You can use the address models as fields in your own models, or as abstract base classes.
- Custom field options: All custom address fields accept standard Django field options (
null,blank,default,help_text, etc.).
Requirements
- Django >= 3.2
- djangorestframework
- django-filter
Development & Testing
- Clone the repo and install in editable mode:
git clone https://github.com/ashkanhasani/django-hierarchical-address.git cd django-hierarchical-address pip install -e .
- Run the example project:
cd example_project python manage.py migrate python manage.py createsuperuser python manage.py runserver
- Access the admin at
http://127.0.0.1:8000/admin/and the API athttp://127.0.0.1:8000/api/places/
FAQ
Q: Can I use my own models for Country, City, etc.? A: Yes! You can subclass or swap out any model. Just ensure you maintain the foreign key relationships.
Q: How do I add more fields to Address? A: Subclass the Address model and add your fields, or use a OneToOneField to extend it.
Q: Can I use this in a multi-tenant or multi-language project? A: Yes, the models are designed to be extensible. For multi-language, consider using django-parler or similar.
Q: Can I use address models as fields instead of relations? A: Yes! You can use the address models as fields in your own models, or as abstract base classes for embedded address data. All standard Django field options are supported for these fields.
License
MIT
Contributing
Pull requests and issues are welcome! Please see the repo for guidelines.
Credits
- Django REST Framework
- django-filter
- Inspired by real-world address needs and open data standards.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_hierarchical_address-0.2.0.tar.gz.
File metadata
- Download URL: django_hierarchical_address-0.2.0.tar.gz
- Upload date:
- Size: 9.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
88cb290b399c937d6e3d75e40d04ea1fdd7c5761d9f06a0cc4315b27d1631fa9
|
|
| MD5 |
3c4a322795146149eef9bd4540b7bbd8
|
|
| BLAKE2b-256 |
311a61c84b3cc2ee1cf2cbe1a87cbe4878a47ac0bf4e647a868522ab9676989d
|
File details
Details for the file django_hierarchical_address-0.2.0-py3-none-any.whl.
File metadata
- Download URL: django_hierarchical_address-0.2.0-py3-none-any.whl
- Upload date:
- Size: 11.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ab454ced5d8763ecf8d2a8984df2378eba2cf52f907a356a8898d176047d4c0c
|
|
| MD5 |
70029185558a3a7eb0bc19b026e513c0
|
|
| BLAKE2b-256 |
1d1bf59d8b41e371d322cc2311a97b049005bb7e2ca6cd6d48bbcab1991b7010
|