django-naija
Django and Django REST framework fields for Nigerian data, built on naija-data: phone numbers (strict NCC validation), NUBAN account numbers (CBN check digit), vehicle plate numbers, states and LGAs.
Website and playground: https://naija-data.asgatcreation.workers.dev · REST API: https://naija-data-api.asgatcreation.workers.dev/v1
pip install django-naija # Django fields, forms and validators
pip install "django-naija[rest]" # plus Django REST framework fields
Requires Python 3.10+ and Django 5.2+.
Models
from django.db import models
from django_naija.fields import LGAField, NigerianPhoneField, NUBANField, PlateNumberField, StateField
class Customer(models.Model):
phone = NigerianPhoneField(types=["mobile"]) # stored as "+2348031234567"
state = StateField() # stored as "LA", 37 choices
lga = LGAField() # stored as "NG025011", 774 choices grouped by state
plate = PlateNumberField(blank=True) # stored as "KJA123AB"
account_number = NUBANField(blank=True) # stored as "0123456789"
Choices are loaded lazily (Django's callable choices), so migrations stay small.
Forms
from django import forms
from django_naija import forms as ngforms
class PayoutForm(ngforms.StateLGAFormMixin, ngforms.NUBANFormMixin, forms.Form):
phone = ngforms.NigerianPhoneField(types=["mobile"])
state = ngforms.StateField()
lga = ngforms.LGAField() # limited to the chosen state; must belong to it
bank = ngforms.BankField() # banks with a CBN code
account_number = ngforms.NUBANField() # checked against the chosen bank
For a dependent state → LGA menu, django_naija.choices.lga_choices("LA") returns the LGAs of one
state; the example project serves it as JSON at /lgas/?state=Lagos.
Django REST framework
from rest_framework import serializers
from django_naija import rest_framework as ngdrf
class PayoutSerializer(serializers.Serializer):
phone = ngdrf.NigerianPhoneField(types=["mobile"])
state = ngdrf.StateField() # also accepts "Lagos", "Abuja", "FCT"
lga = ngdrf.LGAField() # also accepts INEC codes and unambiguous names
bank = ngdrf.BankField() # also accepts "058" or "GTB"
account_number = ngdrf.NUBANField()
class Meta:
validators = [ngdrf.LGAInStateValidator(), ngdrf.NUBANBankValidator()]
Error messages
Every failure has a clear, translatable message and a machine-readable code, e.g.
reserved → "This number range is reserved and not in service.",
check_digit → "This account number is not valid for the selected bank.".
See django_naija/messages.py.
Example project
example/ is a small Django project using every field (model, form, DRF API, dependent LGA
endpoint). The tests in tests/ run against it:
pip install -e "packages/python" -e "packages/django[test]"
cd packages/django && python -m pytest
Plate numbers: only the format is checked. FRSC does not publish its list of LGA plate codes, so plates are not mapped to LGAs yet.
Licence: MIT. Data from naija-data: CC BY 4.0, Akanji Oluwaseun Gabriel.
Metadata
Release files for django-naija 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_naija-1.0.0.tar.gz | 11.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_naija-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 23.2 kB
Release files / django_naija-1.0.0.tar.gz
| Download URL | django_naija-1.0.0.tar.gz |
|---|---|
| Size | 11.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d0c7ddb0a7e40316bd3302461c588604c518337b548b3d59c8eb31e1ce23853a
|
|
BLAKE2b-256 checksum How to use checksums |
a85f445f547b9ae49ad42e0db24aa85f6c827d9f1d3a631bc4adaf4becef3605
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.
Transparency logRelease files / django_naija-1.0.0-py3-none-any.whl
| Download URL | django_naija-1.0.0-py3-none-any.whl |
|---|---|
| Size | 11.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
04e179a982dc472a6b7690536ddf033443d2d90c943082c2419fa5b9090e5aed
|
|
BLAKE2b-256 checksum How to use checksums |
16025a9025c373f534cd0ef1d613b817b38b573de5941f60eec7690a90e7db61
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.
Transparency log