A Django application that provides country choices for use with forms, flag icons static files, and a country field for models.
—
GraphQL type definitions for country data integration with graphene-django. The GraphQL support provides structured country information for GraphQL APIs with complete country metadata access.
GraphQL support requires the graphene-django package:
pip install graphene-djangoGraphQL ObjectType for representing country data with all ISO 3166-1 codes and names.
import graphene
class Country(graphene.ObjectType):
"""GraphQL type for country representation."""
name = graphene.String(description="Country name")
code = graphene.String(description="ISO 3166-1 two character country code")
alpha3 = graphene.String(description="ISO 3166-1 three character country code")
numeric = graphene.Int(description="ISO 3166-1 numeric country code")
ioc_code = graphene.String(description="International Olympic Committee country code")
@staticmethod
def resolve_name(country, info):
"""Resolve country name."""
return country.name
@staticmethod
def resolve_code(country, info):
"""Resolve country code."""
return country.code
@staticmethod
def resolve_alpha3(country, info):
"""Resolve alpha3 country code."""
return country.alpha3
@staticmethod
def resolve_numeric(country, info):
"""Resolve numeric country code."""
return country.numeric
@staticmethod
def resolve_ioc_code(country, info):
"""Resolve IOC country code."""
return country.ioc_codeimport graphene
from django_countries.graphql.types import Country
from django_countries import countries
from django_countries.fields import Country as CountryObject
class Query(graphene.ObjectType):
country = graphene.Field(Country, code=graphene.String())
countries = graphene.List(Country)
def resolve_country(self, info, code=None):
"""Get single country by code."""
if code:
country_obj = CountryObject(code=code)
if country_obj.code: # Validate country exists
return country_obj
return None
def resolve_countries(self, info):
"""Get all countries."""
return [CountryObject(code=country.code) for country in countries]
schema = graphene.Schema(query=Query)import graphene
from graphene_django import DjangoObjectType
from django_countries.graphql.types import Country
from myapp.models import Person
class PersonType(DjangoObjectType):
"""GraphQL type for Person model with country field."""
country = graphene.Field(Country)
class Meta:
model = Person
fields = ['id', 'name', 'country']
def resolve_country(self, info):
"""Resolve country field to Country GraphQL type."""
return self.country # CountryField automatically provides Country object
class Query(graphene.ObjectType):
person = graphene.Field(PersonType, id=graphene.ID())
people = graphene.List(PersonType)
def resolve_person(self, info, id):
try:
return Person.objects.get(id=id)
except Person.DoesNotExist:
return None
def resolve_people(self, info):
return Person.objects.all()import graphene
from django_countries.graphql.types import Country
from django_countries import countries
from django_countries.fields import Country as CountryObject
class CountryQueries(graphene.ObjectType):
"""Extended country queries."""
country = graphene.Field(
Country,
code=graphene.String(description="Country code (alpha2, alpha3, or numeric)")
)
countries = graphene.List(
Country,
name_contains=graphene.String(description="Filter by name containing text"),
first=graphene.Int(description="Limit number of results")
)
countries_by_region = graphene.List(
Country,
region=graphene.String(description="Filter by region/continent")
)
def resolve_country(self, info, code):
"""Get country by any code format."""
country_obj = CountryObject(code=code)
return country_obj if country_obj.code else None
def resolve_countries(self, info, name_contains=None, first=None):
"""Get countries with optional filtering."""
country_list = []
for country_tuple in countries:
country_obj = CountryObject(code=country_tuple.code)
# Filter by name if specified
if name_contains and name_contains.lower() not in country_obj.name.lower():
continue
country_list.append(country_obj)
# Limit results if specified
if first and len(country_list) >= first:
break
return country_list
def resolve_countries_by_region(self, info, region):
"""Get countries by region (example implementation)."""
# This would require additional regional data
# Implementation depends on your regional classification needs
european_countries = ["DE", "FR", "IT", "ES", "NL", "BE", "AT", "PT"]
if region.lower() == "europe":
return [CountryObject(code=code) for code in european_countries]
return []
# Add to main query
class Query(CountryQueries, graphene.ObjectType):
pass# Get single country
query GetCountry {
country(code: "US") {
name
code
alpha3
numeric
iocCode
}
}
# Get all countries
query GetAllCountries {
countries {
name
code
alpha3
}
}
# Get countries with filtering
query GetFilteredCountries {
countries(nameContains: "United", first: 5) {
name
code
}
}
# Get person with country details
query GetPersonWithCountry {
person(id: "1") {
name
country {
name
code
alpha3
flag
}
}
}
# Get all people with their countries
query GetPeopleWithCountries {
people {
name
country {
name
code
}
}
}// Single country query response
{
"data": {
"country": {
"name": "United States",
"code": "US",
"alpha3": "USA",
"numeric": 840,
"iocCode": "USA"
}
}
}
// Countries list response
{
"data": {
"countries": [
{
"name": "Afghanistan",
"code": "AF",
"alpha3": "AFG"
},
{
"name": "Albania",
"code": "AL",
"alpha3": "ALB"
}
]
}
}
// Person with country response
{
"data": {
"person": {
"name": "John Doe",
"country": {
"name": "United States",
"code": "US",
"alpha3": "USA"
}
}
}
}import graphene
from django_countries.graphql.types import Country as BaseCountry
from django_countries.fields import Country as CountryObject
class ExtendedCountry(BaseCountry):
"""Extended country type with additional fields."""
flag_url = graphene.String(description="Flag image URL")
region = graphene.String(description="Geographic region")
@staticmethod
def resolve_flag_url(country, info):
"""Resolve flag URL."""
return country.flag
@staticmethod
def resolve_region(country, info):
"""Resolve geographic region (custom implementation)."""
# Example regional mapping
regions = {
"US": "North America",
"CA": "North America",
"MX": "North America",
"DE": "Europe",
"FR": "Europe",
"GB": "Europe"
}
return regions.get(country.code, "Unknown")
class ExtendedQuery(graphene.ObjectType):
country = graphene.Field(ExtendedCountry, code=graphene.String())
def resolve_country(self, info, code):
country_obj = CountryObject(code=code)
return country_obj if country_obj.code else Noneimport graphene
from django_countries.graphql.types import Country
from myapp.models import Person
class UpdatePersonCountry(graphene.Mutation):
"""Mutation to update person's country."""
class Arguments:
person_id = graphene.ID(required=True)
country_code = graphene.String(required=True)
person = graphene.Field(PersonType)
success = graphene.Boolean()
def mutate(self, info, person_id, country_code):
try:
person = Person.objects.get(id=person_id)
person.country = country_code
person.save()
return UpdatePersonCountry(person=person, success=True)
except Person.DoesNotExist:
return UpdatePersonCountry(person=None, success=False)
class Mutation(graphene.ObjectType):
update_person_country = UpdatePersonCountry.Field()
# Mutation example
"""
mutation UpdateCountry {
updatePersonCountry(personId: "1", countryCode: "CA") {
success
person {
name
country {
name
code
}
}
}
}
"""import graphene
from channels_graphql_ws import Subscription
from django_countries.graphql.types import Country
from myapp.models import Person
class CountryUpdates(Subscription):
"""Subscription for country-related updates."""
country_updated = graphene.Field(Country)
def subscribe(self, info, **kwargs):
"""Subscribe to country updates."""
return ["country_updates"]
def publish(self, info, **kwargs):
"""Publish country update."""
return CountryUpdates(country_updated=kwargs.get("country"))
class Subscription(graphene.ObjectType):
country_updates = CountryUpdates.Field()import graphene
from django_countries.graphql.types import Country
from django_countries.fields import Country as CountryObject
class CountryError(graphene.ObjectType):
"""Error type for country operations."""
message = graphene.String()
code = graphene.String()
class CountryResult(graphene.Union):
"""Union type for country results."""
class Meta:
types = (Country, CountryError)
class SafeQuery(graphene.ObjectType):
country = graphene.Field(CountryResult, code=graphene.String())
def resolve_country(self, info, code):
"""Get country with error handling."""
try:
country_obj = CountryObject(code=code)
if country_obj.code:
return country_obj
else:
return CountryError(
message=f"Country with code '{code}' not found",
code="COUNTRY_NOT_FOUND"
)
except Exception as e:
return CountryError(
message=f"Error retrieving country: {str(e)}",
code="COUNTRY_ERROR"
)import graphene
from django.utils.functional import cached_property
from django_countries.graphql.types import Country
from django_countries import countries
class OptimizedQuery(graphene.ObjectType):
"""Optimized country queries with caching."""
@cached_property
def _countries_cache(self):
"""Cache countries list for better performance."""
return {country.code: country for country in countries}
country = graphene.Field(Country, code=graphene.String())
countries = graphene.List(Country)
def resolve_country(self, info, code):
"""Optimized country lookup."""
country_tuple = self._countries_cache.get(code.upper())
if country_tuple:
return CountryObject(code=country_tuple.code)
return None
def resolve_countries(self, info):
"""Optimized countries list."""
# Use cached data to avoid repeated database/memory access
return [CountryObject(code=ct.code) for ct in self._countries_cache.values()]Install with Tessl CLI
npx tessl i tessl/pypi-django-countries