25👍
from django_countries.fields import CountryField
class Foo(models.Model):
country = CountryField()
35👍
Check out “choices” parameter of a CharField.
You might also want to take a look at django-countries.
- [Django]-Can someone explain how contribute_to_class works?
- [Django]-'dict' object has no attribute 'id'
- [Django]-Django Admin Show Image from Imagefield
11👍
Ended up using the below snippet which basically defines a tuple of tuples of two character country codes. Additionally it defines a custom field type called CountryField and defaults the choices parameter to the above defined tuple. This automatically gets rendered as a drop down list.
- [Django]-Django test app error – Got an error creating the test database: permission denied to create database
- [Django]-JQuery.getJSON doesn't trigger callback
- [Django]-Select between two dates with Django
8👍
Django Countries
from django_countries.countries import COUNTRIES
class CountryForm(forms.Form):
country= forms.ChoiceField(COUNTRIES)
- [Django]-Naming Python loggers
- [Django]-Django import error – No module named core.management
- [Django]-Django >= 3.1 and is_ajax
5👍
Two low mantained projects:
http://code.google.com/p/django-countries/
https://github.com/strange/django-country-utils
Two snippets:
http://djangosnippets.org/snippets/494/
http://djangosnippets.org/snippets/1476/
For now, I am going for a snippet.
- [Django]-How to return an rest_framework.response object from a django custom middleware class?
- [Django]-Django SUM Query?
- [Django]-How to monkey patch Django?
5👍
As previous answers have stated, there is a CountryField
in django-countries
. This is a model field.
If a form field is needed in a plain form (not model form), in django-countries
v3.x (definitely tested in 3.3) the following can be used:
from django_countries.data import COUNTRIES
class MyForm(forms.Form):
country = forms.ChoiceField(sorted(COUNTRIES.items()))
- [Django]-How can I have two foreign keys to the same model in Django?
- [Django]-Django test FileField using test fixtures
- [Django]-FileUploadParser doesn't get the file name
4👍
UPDATE (Django >=4.0)
Using pytz.country_names
was convenient in older Django versions, as described below, but Django >=4.0 uses zoneinfo
instead of pytz
. Details in the release notes and here.
Unfortunately, zoneinfo
does not appear to offer an equivalent of pytz.country_names
(as far as I know).
There is, however, an up-to-date list of ISO 3166 country names in Python’s (first-party) tzdata
package: iso3166.tab
Note that tzdata
is already installed if you’re using Django 4+ on Windows.
For illustrative purposes only, here’s a quick & dirty way to parse the iso3166.tab file into a dict
similar to pytz.country_names
(Python 3.9+):
from importlib import resources
with resources.files('tzdata.zoneinfo').joinpath('iso3166.tab').open('r') as f:
country_names = dict(
line.rstrip('\n').split('\t', 1)
for line in f
if not line.startswith('#')
)
Note, for Django’s field choices
, it would be easier to create a list
directly, instead of a dict
.
ORIGINAL (Django <4.0)
Django (<4.0) uses pytz
(see e.g. django.utils.timezone), and pytz
exposes a country_names
dictionary, based on ISO 3166 (see pytz docs).
This pytz.country_names
dictionary can be used to set your model field choices, or form field choices.
This might not cover all edge cases, but, at least, it does not add another obscure external dependency to your Django project.
Example for a model field (import pytz
first):
country = models.CharField(max_length=2, choices=pytz.country_names.items())
Note that the dict keys (country codes) are all capitals.
One other thing to keep in mind, in case pytz
is updated: as mentioned in the Django Model field reference
A new migration is created each time the order of
choices
changes.
- [Django]-Cannot apply DjangoModelPermissions on a view that does not have `.queryset` property or overrides the `.get_queryset()` method
- [Django]-ValueError: libcublas.so.*[0-9] not found in the system path
- [Django]-DEBUG = True Django
3👍
Here is a nice library with countries (and not only): pycountry
Its main advantage is that it is a wrapper around Debian package pkg-isocodes (thus can updates automatically with it) compared to hard-coded countries in other solutions. It also has translations.
So if new country appears or existing countries will be merged together you do not need to change your code.
I found it useful to use this library and create a simple Django app with model Country for example
Then you can populate and keep up-to-date your ‘country’ table by means of custom django-admin command as described here: Writing custom django-admin commands
- [Django]-How should I use DurationField in my model?
- [Django]-Django Call Class based view from another class based view
- [Django]-Django: why i can't get the tracebacks (in case of error) when i run LiveServerTestCase tests?
- [Django]-Django set default form values
- [Django]-How to delete an object using Django Rest Framework
- [Django]-Non-global middleware in Django
1👍
I solved it by using multiple=True
:
from django_countries.fields import CountryField
class UserProfile(models.Model):
countries = CountryField(multiple=True)
You can read more about it in the docs:
- [Django]-Factory-boy create a list of SubFactory for a Factory
- [Django]-How to automatically login a user after registration in django
- [Django]-Django REST Framework (DRF): TypeError: register() got an unexpected keyword argument 'base_name'
1👍
Link to package : django-countries
If looking for how to do it in forms :
$ pip install django-countries
>>> from django_countries.data import COUNTRIES
>>> Country = forms.ChoiceField(choices = sorted(COUNTRIES.items()))
- [Django]-Django Rest framework, how to include '__all__' fields and a related field in ModelSerializer ?
- [Django]-Getting the SQL from a Django QuerySet
- [Django]-Nginx is throwing an 403 Forbidden on Static Files
1👍
If you just want to have a country ChoiceField without installing django-choices you can create an extra file which holds a tuple with all choices from the Wikipedia Iso Country Codes:
import csv
# Get the file from: "http://geohack.net/gis/wikipedia-iso-country-codes.csv"
with open("wikipedia-iso-country-codes.csv") as f:
file = csv.DictReader(f, delimiter=',')
country_names = [line['English short name lower case'] for line in file]
# Create a tuple with the country names
with open("country_names.py", 'w') as f:
f.write('COUNTRY_CHOICES = (\n')
for c in country_names:
f.write(f' ("{c}", "{c}"),\n')
f.write(')')
The created country_names.py file looks something like this:
COUNTRY_CHOICES = (
("Afghanistan", "Afghanistan"),
("Åland Islands", "Åland Islands"),
("Albania", "Albania"),
("Algeria", "Algeria"),
("American Samoa", "American Samoa"),
...
)
You can then use COUNTRY_CHOICES in your form like this:
from django import forms
from country_names import COUNTRY_CHOICES
class CountryForm(forms.Form):
country= forms.ChoiceField(choices=COUNTRY_CHOICES)
- [Django]-Remove the default delete action in Django admin
- [Django]-Invalid block tag : 'endblock'. Did you forget to register or load this tag?
- [Django]-Redirecting after AJAX post in Django
0👍
Here is the solution:
from django_countries.fields import CountryField
class Foo(TimeStampedModel):
country = CountryField()
- [Django]-Get the name of a decorated function?
- [Django]-Unique validation on nested serializer on Django Rest Framework
- [Django]-How to add a new field to a model with new Django migrations?
0👍
SmileyChris seems to be pretty busy and unavailable, as the repository hasn’t been updated since September. Thankfully, there is a repository that can be forked that is compatible with Django 3 and higher. This can be found here:
https://github.com/yunojuno/django-countries/tree/django-30
It passes all checks for a pull request, however SmileyChris has not responded to the merge request.
To install it just run pip install git+https://github.com/yunojuno/django-countries.git
- [Django]-Right way to return proxy model instance from a base model instance in Django?
- [Django]-How can I make a trailing slash optional on a Django Rest Framework SimpleRouter
- [Django]-How to group models in django admin?
0👍
If you are extending forms.Form class then you have to specify .formfield right after your Countryfield and then specify your attributes in formfield() parameter.
from django_countries.fields import CountryField
class CheckOutForm(forms.Form):
country = CountryField().formfield()
But if you are extending from models.Model class then defining Coutryfield is enough.
from django_countries.fields import CountryField
class CheckOutForm(models.Model):
country = CountryField()
- [Django]-Django models, custom functions
- [Django]-What's the best option to process credit card payments in Django?
- [Django]-Django migration with uuid field generates duplicated values
0👍
I guess, instead of trying with models fields such as ChoiceField
or CharField
and passing ‘choices’ as a parameter which contains list of countries as tuple values inside the list created outside in the models.py, Django has compact library to work with selecting country while filling the form.
from django-countries.fields import CountryField
class foo(models.Model):
country = CountryField(blank_label='select country')
...
- [Django]-Adding django admin permissions in a migration: Permission matching query does not exist
- [Django]-Django suffix ForeignKey field with _id
- [Django]-Django gunicorn sock file not created by wsgi