A Django application that provides country choices for use with forms, flag icons static files, and a country field for models.
—
Django model field for storing country codes with rich Country object functionality. The CountryField provides automatic Country object descriptors, validation, and supports both single and multiple country selection with extensive customization options.
Django model field that stores country codes as CharField but provides Country objects with full country details including names, flags, and alternative codes.
class CountryField(models.CharField):
def __init__(
self,
countries=None,
countries_flag_url=None,
countries_str_attr="code",
blank_label=None,
multiple=None,
multiple_unique=True,
multiple_sort=True,
**kwargs
):
"""
Django model field for country selection.
Parameters:
- countries: Countries class - Custom countries instance for field
- countries_flag_url: str - Custom flag URL pattern override
- countries_str_attr: str - Attribute to use for string representation ("code", "name")
- blank_label: str - Label to use for blank choice in forms
- multiple: bool - Allow multiple country selection
- multiple_unique: bool - Ensure unique values in multiple selection
- multiple_sort: bool - Sort multiple selected values
- **kwargs: Standard CharField arguments (max_length, null, blank, etc.)
"""Usage examples:
from django.db import models
from django_countries.fields import CountryField
# Basic usage
class Person(models.Model):
country = CountryField()
# With custom options
class Organization(models.Model):
countries = CountryField(
multiple=True,
blank_label="(select countries)"
)
# With custom flag URL
class Event(models.Model):
country = CountryField(countries_flag_url="custom/flags/{code}.png")
# Using name as string representation
class Location(models.Model):
country = CountryField(countries_str_attr="name")Individual country representation automatically provided by CountryField descriptor with access to country metadata and flag URLs.
class Country:
def __init__(
self,
code: str,
flag_url: Optional[str] = None,
str_attr: str = "code",
custom_countries: Optional[Countries] = None
):
"""
Individual country object with metadata access.
Parameters:
- code: str - Country code (alpha2, alpha3, or numeric)
- flag_url: str - Custom flag URL pattern
- str_attr: str - Attribute for string representation
- custom_countries: Countries - Custom countries instance
"""
@property
def name(self) -> str:
"""Country name in current language"""
@property
def flag(self) -> str:
"""Flag URL based on flag_url pattern"""
@property
def alpha3(self) -> str:
"""ISO 3166-1 three letter country code"""
@property
def numeric(self) -> Optional[int]:
"""ISO 3166-1 numeric country code"""
@property
def ioc_code(self) -> str:
"""International Olympic Committee code"""
@property
def numeric_padded(self) -> Optional[str]:
"""ISO 3166-1 numeric country code as zero-padded string"""
@property
def flag_css(self) -> str:
"""CSS classes for displaying country flag as sprite"""
@property
def unicode_flag(self) -> str:
"""Unicode flag emoji representation"""
@staticmethod
def country_from_ioc(ioc_code: str, flag_url: str = "") -> Optional['Country']:
"""Create Country object from IOC code"""
def __str__(self) -> str:
"""String representation based on str_attr"""
def __eq__(self, other) -> bool:
"""Equality comparison with country codes"""
def __bool__(self) -> bool:
"""Boolean conversion - True if valid country code"""Usage examples:
# Accessing country object properties
person = Person.objects.get(id=1)
print(person.country.name) # "United States"
print(person.country.code) # "US"
print(person.country.flag) # "/static/flags/us.gif"
print(person.country.alpha3) # "USA"
print(person.country.numeric) # 840
print(person.country.numeric_padded) # "840"
print(person.country.flag_css) # "flag-sprite flag-u flag-_s"
print(person.country.unicode_flag) # "🇺🇸"
# Create country from IOC code
olympic_country = Country.country_from_ioc("USA")
print(olympic_country.code) # "US"
# Country object comparisons
if person.country == "US":
print("American person")
# Multiple countries
org = Organization.objects.get(id=1)
for country in org.countries:
print(f"{country.code}: {country.name}")Specialized lookup types for querying countries by name patterns, providing case-sensitive and case-insensitive searches with various matching strategies.
# Available lookups for CountryField
field__name_exact = "United States" # Exact country name match
field__name_iexact = "united states" # Case-insensitive exact match
field__name_contains = "United" # Country name contains text
field__name_icontains = "united" # Case-insensitive contains
field__name_startswith = "United" # Country name starts with text
field__name_istartswith = "united" # Case-insensitive starts with
field__name_endswith = "States" # Country name ends with text
field__name_iendswith = "states" # Case-insensitive ends with
field__name_regex = r"^United.*" # Regular expression match
field__name_iregex = r"^united.*" # Case-insensitive regex matchUsage examples:
from myapp.models import Person
# Find people from countries containing "United"
people = Person.objects.filter(country__name_contains="United")
# Case-insensitive search for countries starting with "united"
people = Person.objects.filter(country__name_istartswith="united")
# Regex search for countries ending with "land"
people = Person.objects.filter(country__name_regex=r".*land$")Use custom Countries instances for specialized country lists or configurations per field.
from django_countries import Countries
# Create custom countries instance
eu_countries = Countries()
eu_countries.only = ["DE", "FR", "IT", "ES", "NL", "BE"]
class EuropeanEvent(models.Model):
country = CountryField(countries=eu_countries)Enable multiple country selection with validation and sorting options:
class MultiNationalOrg(models.Model):
# Allow multiple countries, ensure uniqueness, keep sorted
operating_countries = CountryField(
multiple=True,
multiple_unique=True,
multiple_sort=True,
blank=True
)
# Multiple countries without sorting
regions = CountryField(
multiple=True,
multiple_sort=False
)Configure custom flag image patterns:
class CustomFlagModel(models.Model):
# Use PNG flags in custom directory
country = CountryField(
countries_flag_url="assets/flags/{code_upper}.png"
)
# Use external flag service
country2 = CountryField(
countries_flag_url="https://flags.example.com/{code}.svg"
)The flag URL pattern supports these format variables:
{code}: lowercase country code{code_upper}: uppercase country codeControl how Country objects render as strings:
class DisplayModel(models.Model):
# Display country code (default)
country_code = CountryField(countries_str_attr="code")
# Display country name
country_name = CountryField(countries_str_attr="name")
# Usage
obj = DisplayModel(country_code="US", country_name="US")
print(obj.country_code) # "US"
print(obj.country_name) # "United States"Install with Tessl CLI
npx tessl i tessl/pypi-django-countries