django-countries-3.4.1/ 0000775 0001750 0001750 00000000000 12612051266 015237 5 ustar chris chris 0000000 0000000 django-countries-3.4.1/setup.cfg 0000664 0001750 0001750 00000000130 12612051266 017052 0 ustar chris chris 0000000 0000000 [bdist_wheel]
universal = 1
[egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0
django-countries-3.4.1/django_countries.egg-info/ 0000775 0001750 0001750 00000000000 12612051266 022266 5 ustar chris chris 0000000 0000000 django-countries-3.4.1/django_countries.egg-info/dependency_links.txt 0000664 0001750 0001750 00000000001 12612051264 026332 0 ustar chris chris 0000000 0000000
django-countries-3.4.1/django_countries.egg-info/not-zip-safe 0000664 0001750 0001750 00000000001 12475432321 024516 0 ustar chris chris 0000000 0000000
django-countries-3.4.1/django_countries.egg-info/PKG-INFO 0000664 0001750 0001750 00000040121 12612051264 023357 0 ustar chris chris 0000000 0000000 Metadata-Version: 1.1
Name: django-countries
Version: 3.4.1
Summary: Provides a country field for Django models.
Home-page: https://github.com/SmileyChris/django-countries/
Author: Chris Beaven
Author-email: smileychris@gmail.com
License: UNKNOWN
Description: ================
Django Countries
================
A Django application that provides country choices for use with forms, flag
icons static files, and a country field for models.
Installation
============
1. ``pip install django-countries``
2. Add ``django_countries`` to ``INSTALLED_APPS``
CountryField
============
A country field for Django models that provides all ISO 3166-1 countries as
choices.
``CountryField`` is based on Django's ``CharField``, providing choices
corresponding to the official ISO 3166-1 list of countries (with a default
``max_length`` of 2).
Consider the following model using a ``CountryField``::
from django.db import models
from django_countries.fields import CountryField
class Person(models.Model):
name = models.CharField(max_length=100)
country = CountryField()
Any ``Person`` instance will have a ``country`` attribute that you can use to
get details of the person's country::
>>> person = Person(name='Chris', country='NZ')
>>> person.country
Country(code='NZ')
>>> person.country.name
'New Zealand'
>>> person.country.flag
'/static/flags/nz.gif'
This object (``person.country`` in the example) is a ``Country`` instance,
which is described below.
Use ``blank_label`` to set the label for the initial blank choice shown in
forms::
country = CountryField(blank_label='(select country)')
The ``Country`` object
----------------------
An object used to represent a country, instanciated with a two character
country code.
It can be compared to other objects as if it was a string containing the
country code and when evaluated as text, returns the country code.
name
Contains the full country name.
flag
Contains a URL to the flag.
alpha3
The three letter country code for this country.
numeric
The numeric country code for this country (as an integer).
numeric_padded
The numeric country code as a three character 0-padded string.
``CountrySelectWidget``
-----------------------
A widget is included that can show the flag image after the select box
(updated with JavaScript when the selection changes).
When you create your form, you can use this custom widget like normal::
from django_countries.widgets import CountrySelectWidget
class PersonForm(forms.ModelForm):
class Meta:
model = models.Person
fields = ('name', 'country')
widgets = {'country': CountrySelectWidget()}
Pass a ``layout`` text argument to the widget to change the positioning of the
flag and widget. The default layout is::
'{widget}
'
Custom forms
============
If you want to use the countries in a custom form, use the following custom
field to ensure the translatable strings for the country choices are left lazy
until the widget renders::
from django_countries.fields import LazyTypedChoiceField
class CustomForm(forms.Form):
country = LazyTypedChoiceField(choices=countries)
You can also use the CountrySelectWidget_ as the widget for this field if you
want the flag image after the select box.
Get the countries from Python
=============================
Use the ``django_countries.countries`` object instance as an iterator of ISO
3166-1 country codes and names (sorted by name).
For example::
>>> from django_countries import countries
>>> dict(countries)['NZ']
'New Zealand'
>>> for code, name in list(countries)[:3]:
... print("{name} ({code})".format(name=name, code=code))
...
Afghanistan (AF)
Åland Islands (AX)
Albania (AL)
Country names are translated using Django's standard ``ugettext``.
If you would like to help by adding a translation, please visit
https://www.transifex.com/projects/p/django-countries/
Template Tags
=============
If you have your country code stored in a different place than a `CountryField` you can use the template tag to get a `Country` object and have access to all of its properties:
{% load countries %}
{% get_country 'BR' as country %}
{{ country.name }}
Customization
=============
Customize the country list
--------------------------
Country names are taken from the official ISO 3166-1 list. If your project
requires the use of alternative names, the inclusion or exclusion of specific
countries then use the ``COUNTRIES_OVERRIDE`` setting.
A dictionary of names to override the defaults.
Note that you will need to handle translation of customised country names.
Setting a country's name to ``None`` will exclude it from the country list.
For example::
COUNTRIES_OVERRIDE = {
'NZ': _('Middle Earth'),
'AU': None
}
If you have a specific list of countries that should be used, use
``COUNTRIES_ONLY``::
COUNTRIES_ONLY = ['NZ', 'AU']
or to specify your own country names, use a dictionary or two-tuple list
(string items will use the standard country name)::
COUNTRIES_ONLY = [
'US',
'UK'
('NZ', _('Middle Earth')),
('AU', _('Desert')),
]
Show certain countries first
----------------------------
Provide a list of country codes as the ``COUNTRIES_FIRST`` setting and they
will be shown first in the countries list (in the order specified) before all
the alphanumerically sorted countries.
By default, these 'first' countries are not repeated again in the
alphanumerically sorted list. If you would like them to be repeated, set the
``COUNTRIES_FIRST_REPEAT`` setting to ``True``.
Finally, you can optionally separate these 'first' countries with an empty
choice by providing the choice label as the ``COUNTRIES_FIRST_BREAK`` setting.
Customize the flag URL
----------------------
The ``COUNTRIES_FLAG_URL`` setting can be used to set the url for the flag
image assets. It defaults to::
COUNTRIES_FLAG_URL = 'flags/{code}.gif'
The URL can be relative to the STATIC_URL setting, or an absolute URL.
The location is parsed using Python's string formatting and is passed the
following arguments:
* code
* code_upper
For example: ``COUNTRIES_FLAG_URL = 'flags/16x10/{code_upper}.png'``
No checking is done to ensure that a static flag actually exists.
Alternatively, you can specify a different URL on a specific ``CountryField``::
class Person(models.Model):
name = models.CharField(max_length=100)
country = CountryField(
countries_flag_url='//flags.example.com/{code}.png')
Single field customization
--------------------------
To customize an individual field, rather than rely on project level settings,
create a ``Countries`` subclass which overrides settings.
To override a setting, give the class an attribute matching the lowercased
setting without the ``COUNTRIES_`` prefix.
Then just reference this class in a field. For example, this ``CountryField``
uses a custom country list that only includes the G8 countries::
from django_countries import Countries
class G8Countries(Countries):
only = [
'CA', 'FR', 'DE', 'IT', 'JP', 'RU', 'GB',
('EU', _('European Union'))
]
class Vote(models.Model):
country = CountryField(countries=G8Countries)
approve = models.BooleanField()
Django Rest Framework field
===========================
Django Countries ships with a ``CountryField`` serializer field to simplify
the REST interface. For example::
class PersonSerializer(serializers.ModelSerializer):
country = CountryField()
class Meta:
model = models.Person
fields = ('name', 'email', 'country')
You can optionally instanciate the field with ``countries`` with a custom
Countries_ instance.
.. _Countries: Single field customization_
REST output format
------------------
By default, the field will output just the country code. If you would rather
have more verbose output, instanciate the field with ``country_dict=True``,
which will result in the field having the following output structure::
{"code": "NZ", "name": "New Zealand"}
Either the code or this dict output structure are acceptible as input
irregardless of the ``country_dict`` argument's value.
==========
Change Log
==========
This log shows interesting changes that happen for each version, latest
versions first. It can be assumed that translations have been updated each
release (and any new translations added).
Version 3.4 (22 October 2015)
=============================
* Extend test suite to cover Django 1.8
* Fix XSS escaping issue in CountrySelectWidget
* Common name changes: fix typo of Moldova, add United Kingdom
* Add ``{% get_country %}`` template tag.
* New ``CountryField`` Django Rest Framework serializer field.
Version 3.4.1
-------------
* Fix minor packaging error.
Version 3.3 (30 Mar 2015)
=========================
* Add the attributes to ``Countries`` class that can override the default
settings.
* CountriesField can now be passed a custom countries subclass to use, which
combined with the previous change allows for different country choices for
different fields.
* Allow ``COUNTRIES_ONLY`` to also accept just country codes in its list
(rather than only two-tuples), looking up the translatable country name from
the full country list.
* Fix Montenegro flag size (was 12px high rather than the standard 11px).
* Fix outdated ISO country name formatting for Bolivia, Gambia, Holy See,
Iran, Micronesia, and Venezuela.
Version 3.2 (24 Feb 2015)
=========================
* Fixes initial iteration failing for a fresh ``Countries`` object.
* Fix widget's flag URLs (and use ensure widget is HTML encoded safely).
* Add ``countries.by_name(country, language='en')`` method, allowing lookup of
a country code by its full country name. Thanks Josh Schneier.
Version 3.1 (15 Jan 2015)
=========================
* Start change log :)
* Add a ``COUNTRIES_FIRST`` setting (and some other related ones) to allow for
specific countries to be shown before the entire alphanumeric list.
* Add a ``blank_label`` argument to ``CountryField`` to allow customization of
the label shown in the initial blank choice shown in the select widget.
Version 3.1.1 (15 Jan 2015)
---------------------------
* Packaging fix (``CHANGES.rst`` wasn't in the manifest)
Version 3.0 (22 Oct 2014)
=========================
Django supported versions are now 1.4 (LTS) and 1.6+
* Add ``COUNTRIES_ONLY`` setting to restrict to a specific list of countries.
* Optimize country name translations to avoid exessive translation calls that
were causing a notable performance impact.
* PyUCA integration, allowing for more accurate sorting across all locales.
Also, a better sorting method when PyUCA isn't installed.
* Better tests (now at 100% test coverage).
* Add a ``COUNTRIES_FLAG_URL`` setting to allow custom flag urls.
* Support both IOC and numeric country codes, allowing more flexible lookup of
countries and specific code types.
* Field descriptor now returns ``None`` if no country matches (*reverted in v3.0.1*)
Version 3.0.1 (27 Oct 2014)
---------------------------
* Revert descriptor to always return a Country object.
* Fix the ``CountryField`` widget choices appearing empty due to a translation
change in v3.0.
Version 3.0.2 (29 Dec 2014)
---------------------------
* Fix ``CountrySelectWidget`` failing when used with a model form that is
passed a model instance.
Version 2.1 (24 Mar 2014)
=========================
* Add IOC (3 letter) country codes.
* Fix bug when loading fixtures.
Version 2.1.1 (28 Mar 2014)
---------------------------
* Fix issue with translations getting evaluated early.
Version 2.1.2 (28 Mar 2014)
---------------------------
* Fix Python 3 compatibility.
Version 2.0 (18 Feb 2014)
=========================
This is the first entry to the change log. The previous version was 1.5,
released 19 Nov 2012.
* Optimized flag images, adding flags missing from original source.
* Better storage of settings and country list.
* New country list format for fields.
* Better tests.
* Changed ``COUNTRIES_FLAG_STATIC`` setting to ``COUNTRIES_FLAG_URL``.
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Framework :: Django
django-countries-3.4.1/django_countries.egg-info/top_level.txt 0000664 0001750 0001750 00000000021 12612051264 025007 0 ustar chris chris 0000000 0000000 django_countries
django-countries-3.4.1/django_countries.egg-info/SOURCES.txt 0000664 0001750 0001750 00000030764 12612051266 024164 0 ustar chris chris 0000000 0000000 CHANGES.rst
LICENSE
MANIFEST.in
README.rst
setup.cfg
setup.py
tox.ini
django_countries/__init__.py
django_countries/conf.py
django_countries/data.py
django_countries/fields.py
django_countries/ioc_data.py
django_countries/models.py
django_countries/serializer_fields.py
django_countries/widgets.py
django_countries.egg-info/PKG-INFO
django_countries.egg-info/SOURCES.txt
django_countries.egg-info/dependency_links.txt
django_countries.egg-info/not-zip-safe
django_countries.egg-info/top_level.txt
django_countries/locale/ar/LC_MESSAGES/django.mo
django_countries/locale/ar/LC_MESSAGES/django.po
django_countries/locale/cs/LC_MESSAGES/django.mo
django_countries/locale/cs/LC_MESSAGES/django.po
django_countries/locale/de/LC_MESSAGES/django.mo
django_countries/locale/de/LC_MESSAGES/django.po
django_countries/locale/el/LC_MESSAGES/django.mo
django_countries/locale/el/LC_MESSAGES/django.po
django_countries/locale/en/LC_MESSAGES/django.mo
django_countries/locale/en/LC_MESSAGES/django.po
django_countries/locale/eo/LC_MESSAGES/django.mo
django_countries/locale/eo/LC_MESSAGES/django.po
django_countries/locale/es/LC_MESSAGES/django.mo
django_countries/locale/es/LC_MESSAGES/django.po
django_countries/locale/et/LC_MESSAGES/django.mo
django_countries/locale/et/LC_MESSAGES/django.po
django_countries/locale/fa/LC_MESSAGES/django.mo
django_countries/locale/fa/LC_MESSAGES/django.po
django_countries/locale/fi/LC_MESSAGES/django.mo
django_countries/locale/fi/LC_MESSAGES/django.po
django_countries/locale/fr/LC_MESSAGES/django.mo
django_countries/locale/fr/LC_MESSAGES/django.po
django_countries/locale/hr/LC_MESSAGES/django.mo
django_countries/locale/hr/LC_MESSAGES/django.po
django_countries/locale/it/LC_MESSAGES/django.mo
django_countries/locale/it/LC_MESSAGES/django.po
django_countries/locale/ja/LC_MESSAGES/django.mo
django_countries/locale/ja/LC_MESSAGES/django.po
django_countries/locale/nb/LC_MESSAGES/django.mo
django_countries/locale/nb/LC_MESSAGES/django.po
django_countries/locale/nl/LC_MESSAGES/django.mo
django_countries/locale/nl/LC_MESSAGES/django.po
django_countries/locale/pl/LC_MESSAGES/django.mo
django_countries/locale/pl/LC_MESSAGES/django.po
django_countries/locale/pt_BR/LC_MESSAGES/django.mo
django_countries/locale/pt_BR/LC_MESSAGES/django.po
django_countries/locale/pt_PT/LC_MESSAGES/django.mo
django_countries/locale/pt_PT/LC_MESSAGES/django.po
django_countries/locale/ru/LC_MESSAGES/django.mo
django_countries/locale/ru/LC_MESSAGES/django.po
django_countries/locale/sk/LC_MESSAGES/django.mo
django_countries/locale/sk/LC_MESSAGES/django.po
django_countries/locale/sv/LC_MESSAGES/django.mo
django_countries/locale/sv/LC_MESSAGES/django.po
django_countries/locale/tr_TR/LC_MESSAGES/django.mo
django_countries/locale/tr_TR/LC_MESSAGES/django.po
django_countries/locale/uk/LC_MESSAGES/django.mo
django_countries/locale/uk/LC_MESSAGES/django.po
django_countries/locale/zh_CN/LC_MESSAGES/django.mo
django_countries/locale/zh_CN/LC_MESSAGES/django.po
django_countries/static/flags/__.gif
django_countries/static/flags/ad.gif
django_countries/static/flags/ae.gif
django_countries/static/flags/af.gif
django_countries/static/flags/ag.gif
django_countries/static/flags/ai.gif
django_countries/static/flags/al.gif
django_countries/static/flags/am.gif
django_countries/static/flags/ao.gif
django_countries/static/flags/aq.gif
django_countries/static/flags/ar.gif
django_countries/static/flags/as.gif
django_countries/static/flags/at.gif
django_countries/static/flags/au.gif
django_countries/static/flags/aw.gif
django_countries/static/flags/ax.gif
django_countries/static/flags/az.gif
django_countries/static/flags/ba.gif
django_countries/static/flags/bb.gif
django_countries/static/flags/bd.gif
django_countries/static/flags/be.gif
django_countries/static/flags/bf.gif
django_countries/static/flags/bg.gif
django_countries/static/flags/bh.gif
django_countries/static/flags/bi.gif
django_countries/static/flags/bj.gif
django_countries/static/flags/bl.gif
django_countries/static/flags/bm.gif
django_countries/static/flags/bn.gif
django_countries/static/flags/bo.gif
django_countries/static/flags/bq.gif
django_countries/static/flags/br.gif
django_countries/static/flags/bs.gif
django_countries/static/flags/bt.gif
django_countries/static/flags/bv.gif
django_countries/static/flags/bw.gif
django_countries/static/flags/by.gif
django_countries/static/flags/bz.gif
django_countries/static/flags/ca.gif
django_countries/static/flags/cc.gif
django_countries/static/flags/cd.gif
django_countries/static/flags/cf.gif
django_countries/static/flags/cg.gif
django_countries/static/flags/ch.gif
django_countries/static/flags/ci.gif
django_countries/static/flags/ck.gif
django_countries/static/flags/cl.gif
django_countries/static/flags/cm.gif
django_countries/static/flags/cn.gif
django_countries/static/flags/co.gif
django_countries/static/flags/cr.gif
django_countries/static/flags/cu.gif
django_countries/static/flags/cv.gif
django_countries/static/flags/cw.gif
django_countries/static/flags/cx.gif
django_countries/static/flags/cy.gif
django_countries/static/flags/cz.gif
django_countries/static/flags/de.gif
django_countries/static/flags/dj.gif
django_countries/static/flags/dk.gif
django_countries/static/flags/dm.gif
django_countries/static/flags/do.gif
django_countries/static/flags/dz.gif
django_countries/static/flags/ec.gif
django_countries/static/flags/ee.gif
django_countries/static/flags/eg.gif
django_countries/static/flags/eh.gif
django_countries/static/flags/er.gif
django_countries/static/flags/es.gif
django_countries/static/flags/et.gif
django_countries/static/flags/eu.gif
django_countries/static/flags/fi.gif
django_countries/static/flags/fj.gif
django_countries/static/flags/fk.gif
django_countries/static/flags/fm.gif
django_countries/static/flags/fo.gif
django_countries/static/flags/fr.gif
django_countries/static/flags/ga.gif
django_countries/static/flags/gb.gif
django_countries/static/flags/gd.gif
django_countries/static/flags/ge.gif
django_countries/static/flags/gf.gif
django_countries/static/flags/gg.gif
django_countries/static/flags/gh.gif
django_countries/static/flags/gi.gif
django_countries/static/flags/gl.gif
django_countries/static/flags/gm.gif
django_countries/static/flags/gn.gif
django_countries/static/flags/gp.gif
django_countries/static/flags/gq.gif
django_countries/static/flags/gr.gif
django_countries/static/flags/gs.gif
django_countries/static/flags/gt.gif
django_countries/static/flags/gu.gif
django_countries/static/flags/gw.gif
django_countries/static/flags/gy.gif
django_countries/static/flags/hk.gif
django_countries/static/flags/hm.gif
django_countries/static/flags/hn.gif
django_countries/static/flags/hr.gif
django_countries/static/flags/ht.gif
django_countries/static/flags/hu.gif
django_countries/static/flags/id.gif
django_countries/static/flags/ie.gif
django_countries/static/flags/il.gif
django_countries/static/flags/im.gif
django_countries/static/flags/in.gif
django_countries/static/flags/io.gif
django_countries/static/flags/iq.gif
django_countries/static/flags/ir.gif
django_countries/static/flags/is.gif
django_countries/static/flags/it.gif
django_countries/static/flags/je.gif
django_countries/static/flags/jm.gif
django_countries/static/flags/jo.gif
django_countries/static/flags/jp.gif
django_countries/static/flags/ke.gif
django_countries/static/flags/kg.gif
django_countries/static/flags/kh.gif
django_countries/static/flags/ki.gif
django_countries/static/flags/km.gif
django_countries/static/flags/kn.gif
django_countries/static/flags/kp.gif
django_countries/static/flags/kr.gif
django_countries/static/flags/kw.gif
django_countries/static/flags/ky.gif
django_countries/static/flags/kz.gif
django_countries/static/flags/la.gif
django_countries/static/flags/lb.gif
django_countries/static/flags/lc.gif
django_countries/static/flags/li.gif
django_countries/static/flags/lk.gif
django_countries/static/flags/lr.gif
django_countries/static/flags/ls.gif
django_countries/static/flags/lt.gif
django_countries/static/flags/lu.gif
django_countries/static/flags/lv.gif
django_countries/static/flags/ly.gif
django_countries/static/flags/ma.gif
django_countries/static/flags/mc.gif
django_countries/static/flags/md.gif
django_countries/static/flags/me.gif
django_countries/static/flags/mf.gif
django_countries/static/flags/mg.gif
django_countries/static/flags/mh.gif
django_countries/static/flags/mk.gif
django_countries/static/flags/ml.gif
django_countries/static/flags/mm.gif
django_countries/static/flags/mn.gif
django_countries/static/flags/mo.gif
django_countries/static/flags/mp.gif
django_countries/static/flags/mq.gif
django_countries/static/flags/mr.gif
django_countries/static/flags/ms.gif
django_countries/static/flags/mt.gif
django_countries/static/flags/mu.gif
django_countries/static/flags/mv.gif
django_countries/static/flags/mw.gif
django_countries/static/flags/mx.gif
django_countries/static/flags/my.gif
django_countries/static/flags/mz.gif
django_countries/static/flags/na.gif
django_countries/static/flags/nc.gif
django_countries/static/flags/ne.gif
django_countries/static/flags/nf.gif
django_countries/static/flags/ng.gif
django_countries/static/flags/ni.gif
django_countries/static/flags/nl.gif
django_countries/static/flags/no.gif
django_countries/static/flags/np.gif
django_countries/static/flags/nr.gif
django_countries/static/flags/nu.gif
django_countries/static/flags/nz.gif
django_countries/static/flags/om.gif
django_countries/static/flags/pa.gif
django_countries/static/flags/pe.gif
django_countries/static/flags/pf.gif
django_countries/static/flags/pg.gif
django_countries/static/flags/ph.gif
django_countries/static/flags/pk.gif
django_countries/static/flags/pl.gif
django_countries/static/flags/pm.gif
django_countries/static/flags/pn.gif
django_countries/static/flags/pr.gif
django_countries/static/flags/ps.gif
django_countries/static/flags/pt.gif
django_countries/static/flags/pw.gif
django_countries/static/flags/py.gif
django_countries/static/flags/qa.gif
django_countries/static/flags/re.gif
django_countries/static/flags/ro.gif
django_countries/static/flags/rs.gif
django_countries/static/flags/ru.gif
django_countries/static/flags/rw.gif
django_countries/static/flags/sa.gif
django_countries/static/flags/sb.gif
django_countries/static/flags/sc.gif
django_countries/static/flags/sd.gif
django_countries/static/flags/se.gif
django_countries/static/flags/sg.gif
django_countries/static/flags/sh.gif
django_countries/static/flags/si.gif
django_countries/static/flags/sj.gif
django_countries/static/flags/sk.gif
django_countries/static/flags/sl.gif
django_countries/static/flags/sm.gif
django_countries/static/flags/sn.gif
django_countries/static/flags/so.gif
django_countries/static/flags/sr.gif
django_countries/static/flags/ss.gif
django_countries/static/flags/st.gif
django_countries/static/flags/sv.gif
django_countries/static/flags/sx.gif
django_countries/static/flags/sy.gif
django_countries/static/flags/sz.gif
django_countries/static/flags/tc.gif
django_countries/static/flags/td.gif
django_countries/static/flags/tf.gif
django_countries/static/flags/tg.gif
django_countries/static/flags/th.gif
django_countries/static/flags/tj.gif
django_countries/static/flags/tk.gif
django_countries/static/flags/tl.gif
django_countries/static/flags/tm.gif
django_countries/static/flags/tn.gif
django_countries/static/flags/to.gif
django_countries/static/flags/tr.gif
django_countries/static/flags/tt.gif
django_countries/static/flags/tv.gif
django_countries/static/flags/tw.gif
django_countries/static/flags/tz.gif
django_countries/static/flags/ua.gif
django_countries/static/flags/ug.gif
django_countries/static/flags/um.gif
django_countries/static/flags/us.gif
django_countries/static/flags/uy.gif
django_countries/static/flags/uz.gif
django_countries/static/flags/va.gif
django_countries/static/flags/vc.gif
django_countries/static/flags/ve.gif
django_countries/static/flags/vg.gif
django_countries/static/flags/vi.gif
django_countries/static/flags/vn.gif
django_countries/static/flags/vu.gif
django_countries/static/flags/wf.gif
django_countries/static/flags/ws.gif
django_countries/static/flags/ye.gif
django_countries/static/flags/yt.gif
django_countries/static/flags/za.gif
django_countries/static/flags/zm.gif
django_countries/static/flags/zw.gif
django_countries/templatetags/__init__.py
django_countries/templatetags/countries.py
django_countries/tests/__init__.py
django_countries/tests/custom_countries.py
django_countries/tests/forms.py
django_countries/tests/models.py
django_countries/tests/settings.py
django_countries/tests/settings_lts.py
django_countries/tests/test_countries.py
django_countries/tests/test_drf.py
django_countries/tests/test_fields.py
django_countries/tests/test_settings.py
django_countries/tests/test_tags.py
django_countries/tests/test_widgets.py django-countries-3.4.1/setup.py 0000775 0001750 0001750 00000002504 12612051070 016746 0 ustar chris chris 0000000 0000000 #!/usr/bin/env python
import codecs
from setuptools import setup, find_packages
def read_files(*filenames):
"""
Output the contents of one or more files to a single concatenated string.
"""
output = []
for filename in filenames:
f = codecs.open(filename, encoding='utf-8')
try:
output.append(f.read())
finally:
f.close()
return '\n\n'.join(output)
setup(
name='django-countries',
version='3.4.1',
description='Provides a country field for Django models.',
long_description=read_files('README.rst', 'CHANGES.rst'),
author='Chris Beaven',
author_email='smileychris@gmail.com',
url='https://github.com/SmileyChris/django-countries/',
packages=find_packages(),
zip_safe=False,
include_package_data=True,
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Framework :: Django',
],
)
django-countries-3.4.1/README.rst 0000664 0001750 0001750 00000020043 12612047442 016726 0 ustar chris chris 0000000 0000000 ================
Django Countries
================
A Django application that provides country choices for use with forms, flag
icons static files, and a country field for models.
Installation
============
1. ``pip install django-countries``
2. Add ``django_countries`` to ``INSTALLED_APPS``
CountryField
============
A country field for Django models that provides all ISO 3166-1 countries as
choices.
``CountryField`` is based on Django's ``CharField``, providing choices
corresponding to the official ISO 3166-1 list of countries (with a default
``max_length`` of 2).
Consider the following model using a ``CountryField``::
from django.db import models
from django_countries.fields import CountryField
class Person(models.Model):
name = models.CharField(max_length=100)
country = CountryField()
Any ``Person`` instance will have a ``country`` attribute that you can use to
get details of the person's country::
>>> person = Person(name='Chris', country='NZ')
>>> person.country
Country(code='NZ')
>>> person.country.name
'New Zealand'
>>> person.country.flag
'/static/flags/nz.gif'
This object (``person.country`` in the example) is a ``Country`` instance,
which is described below.
Use ``blank_label`` to set the label for the initial blank choice shown in
forms::
country = CountryField(blank_label='(select country)')
The ``Country`` object
----------------------
An object used to represent a country, instanciated with a two character
country code.
It can be compared to other objects as if it was a string containing the
country code and when evaluated as text, returns the country code.
name
Contains the full country name.
flag
Contains a URL to the flag.
alpha3
The three letter country code for this country.
numeric
The numeric country code for this country (as an integer).
numeric_padded
The numeric country code as a three character 0-padded string.
``CountrySelectWidget``
-----------------------
A widget is included that can show the flag image after the select box
(updated with JavaScript when the selection changes).
When you create your form, you can use this custom widget like normal::
from django_countries.widgets import CountrySelectWidget
class PersonForm(forms.ModelForm):
class Meta:
model = models.Person
fields = ('name', 'country')
widgets = {'country': CountrySelectWidget()}
Pass a ``layout`` text argument to the widget to change the positioning of the
flag and widget. The default layout is::
'{widget}
'
Custom forms
============
If you want to use the countries in a custom form, use the following custom
field to ensure the translatable strings for the country choices are left lazy
until the widget renders::
from django_countries.fields import LazyTypedChoiceField
class CustomForm(forms.Form):
country = LazyTypedChoiceField(choices=countries)
You can also use the CountrySelectWidget_ as the widget for this field if you
want the flag image after the select box.
Get the countries from Python
=============================
Use the ``django_countries.countries`` object instance as an iterator of ISO
3166-1 country codes and names (sorted by name).
For example::
>>> from django_countries import countries
>>> dict(countries)['NZ']
'New Zealand'
>>> for code, name in list(countries)[:3]:
... print("{name} ({code})".format(name=name, code=code))
...
Afghanistan (AF)
Åland Islands (AX)
Albania (AL)
Country names are translated using Django's standard ``ugettext``.
If you would like to help by adding a translation, please visit
https://www.transifex.com/projects/p/django-countries/
Template Tags
=============
If you have your country code stored in a different place than a `CountryField` you can use the template tag to get a `Country` object and have access to all of its properties:
{% load countries %}
{% get_country 'BR' as country %}
{{ country.name }}
Customization
=============
Customize the country list
--------------------------
Country names are taken from the official ISO 3166-1 list. If your project
requires the use of alternative names, the inclusion or exclusion of specific
countries then use the ``COUNTRIES_OVERRIDE`` setting.
A dictionary of names to override the defaults.
Note that you will need to handle translation of customised country names.
Setting a country's name to ``None`` will exclude it from the country list.
For example::
COUNTRIES_OVERRIDE = {
'NZ': _('Middle Earth'),
'AU': None
}
If you have a specific list of countries that should be used, use
``COUNTRIES_ONLY``::
COUNTRIES_ONLY = ['NZ', 'AU']
or to specify your own country names, use a dictionary or two-tuple list
(string items will use the standard country name)::
COUNTRIES_ONLY = [
'US',
'UK'
('NZ', _('Middle Earth')),
('AU', _('Desert')),
]
Show certain countries first
----------------------------
Provide a list of country codes as the ``COUNTRIES_FIRST`` setting and they
will be shown first in the countries list (in the order specified) before all
the alphanumerically sorted countries.
By default, these 'first' countries are not repeated again in the
alphanumerically sorted list. If you would like them to be repeated, set the
``COUNTRIES_FIRST_REPEAT`` setting to ``True``.
Finally, you can optionally separate these 'first' countries with an empty
choice by providing the choice label as the ``COUNTRIES_FIRST_BREAK`` setting.
Customize the flag URL
----------------------
The ``COUNTRIES_FLAG_URL`` setting can be used to set the url for the flag
image assets. It defaults to::
COUNTRIES_FLAG_URL = 'flags/{code}.gif'
The URL can be relative to the STATIC_URL setting, or an absolute URL.
The location is parsed using Python's string formatting and is passed the
following arguments:
* code
* code_upper
For example: ``COUNTRIES_FLAG_URL = 'flags/16x10/{code_upper}.png'``
No checking is done to ensure that a static flag actually exists.
Alternatively, you can specify a different URL on a specific ``CountryField``::
class Person(models.Model):
name = models.CharField(max_length=100)
country = CountryField(
countries_flag_url='//flags.example.com/{code}.png')
Single field customization
--------------------------
To customize an individual field, rather than rely on project level settings,
create a ``Countries`` subclass which overrides settings.
To override a setting, give the class an attribute matching the lowercased
setting without the ``COUNTRIES_`` prefix.
Then just reference this class in a field. For example, this ``CountryField``
uses a custom country list that only includes the G8 countries::
from django_countries import Countries
class G8Countries(Countries):
only = [
'CA', 'FR', 'DE', 'IT', 'JP', 'RU', 'GB',
('EU', _('European Union'))
]
class Vote(models.Model):
country = CountryField(countries=G8Countries)
approve = models.BooleanField()
Django Rest Framework field
===========================
Django Countries ships with a ``CountryField`` serializer field to simplify
the REST interface. For example::
class PersonSerializer(serializers.ModelSerializer):
country = CountryField()
class Meta:
model = models.Person
fields = ('name', 'email', 'country')
You can optionally instanciate the field with ``countries`` with a custom
Countries_ instance.
.. _Countries: Single field customization_
REST output format
------------------
By default, the field will output just the country code. If you would rather
have more verbose output, instanciate the field with ``country_dict=True``,
which will result in the field having the following output structure::
{"code": "NZ", "name": "New Zealand"}
Either the code or this dict output structure are acceptible as input
irregardless of the ``country_dict`` argument's value.
django-countries-3.4.1/LICENSE 0000664 0001750 0001750 00000002060 12475430413 016244 0 ustar chris chris 0000000 0000000 Copyright (c) 2010 Chris Beaven and contributors
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE. django-countries-3.4.1/CHANGES.rst 0000664 0001750 0001750 00000007611 12612051134 017040 0 ustar chris chris 0000000 0000000 ==========
Change Log
==========
This log shows interesting changes that happen for each version, latest
versions first. It can be assumed that translations have been updated each
release (and any new translations added).
Version 3.4 (22 October 2015)
=============================
* Extend test suite to cover Django 1.8
* Fix XSS escaping issue in CountrySelectWidget
* Common name changes: fix typo of Moldova, add United Kingdom
* Add ``{% get_country %}`` template tag.
* New ``CountryField`` Django Rest Framework serializer field.
Version 3.4.1
-------------
* Fix minor packaging error.
Version 3.3 (30 Mar 2015)
=========================
* Add the attributes to ``Countries`` class that can override the default
settings.
* CountriesField can now be passed a custom countries subclass to use, which
combined with the previous change allows for different country choices for
different fields.
* Allow ``COUNTRIES_ONLY`` to also accept just country codes in its list
(rather than only two-tuples), looking up the translatable country name from
the full country list.
* Fix Montenegro flag size (was 12px high rather than the standard 11px).
* Fix outdated ISO country name formatting for Bolivia, Gambia, Holy See,
Iran, Micronesia, and Venezuela.
Version 3.2 (24 Feb 2015)
=========================
* Fixes initial iteration failing for a fresh ``Countries`` object.
* Fix widget's flag URLs (and use ensure widget is HTML encoded safely).
* Add ``countries.by_name(country, language='en')`` method, allowing lookup of
a country code by its full country name. Thanks Josh Schneier.
Version 3.1 (15 Jan 2015)
=========================
* Start change log :)
* Add a ``COUNTRIES_FIRST`` setting (and some other related ones) to allow for
specific countries to be shown before the entire alphanumeric list.
* Add a ``blank_label`` argument to ``CountryField`` to allow customization of
the label shown in the initial blank choice shown in the select widget.
Version 3.1.1 (15 Jan 2015)
---------------------------
* Packaging fix (``CHANGES.rst`` wasn't in the manifest)
Version 3.0 (22 Oct 2014)
=========================
Django supported versions are now 1.4 (LTS) and 1.6+
* Add ``COUNTRIES_ONLY`` setting to restrict to a specific list of countries.
* Optimize country name translations to avoid exessive translation calls that
were causing a notable performance impact.
* PyUCA integration, allowing for more accurate sorting across all locales.
Also, a better sorting method when PyUCA isn't installed.
* Better tests (now at 100% test coverage).
* Add a ``COUNTRIES_FLAG_URL`` setting to allow custom flag urls.
* Support both IOC and numeric country codes, allowing more flexible lookup of
countries and specific code types.
* Field descriptor now returns ``None`` if no country matches (*reverted in v3.0.1*)
Version 3.0.1 (27 Oct 2014)
---------------------------
* Revert descriptor to always return a Country object.
* Fix the ``CountryField`` widget choices appearing empty due to a translation
change in v3.0.
Version 3.0.2 (29 Dec 2014)
---------------------------
* Fix ``CountrySelectWidget`` failing when used with a model form that is
passed a model instance.
Version 2.1 (24 Mar 2014)
=========================
* Add IOC (3 letter) country codes.
* Fix bug when loading fixtures.
Version 2.1.1 (28 Mar 2014)
---------------------------
* Fix issue with translations getting evaluated early.
Version 2.1.2 (28 Mar 2014)
---------------------------
* Fix Python 3 compatibility.
Version 2.0 (18 Feb 2014)
=========================
This is the first entry to the change log. The previous version was 1.5,
released 19 Nov 2012.
* Optimized flag images, adding flags missing from original source.
* Better storage of settings and country list.
* New country list format for fields.
* Better tests.
* Changed ``COUNTRIES_FLAG_STATIC`` setting to ``COUNTRIES_FLAG_URL``.
django-countries-3.4.1/django_countries/ 0000775 0001750 0001750 00000000000 12612051266 020574 5 ustar chris chris 0000000 0000000 django-countries-3.4.1/django_countries/ioc_data.py 0000664 0001750 0001750 00000007611 12475430413 022720 0 ustar chris chris 0000000 0000000 IOC_TO_ISO = {
'AFG': 'AF',
'ALB': 'AL',
'ALG': 'DZ',
'AND': 'AD',
'ANG': 'AO',
'ANT': 'AG',
'ARG': 'AR',
'ARM': 'AM',
'ARU': 'AW',
'ASA': 'AS',
'AUS': 'AU',
'AUT': 'AT',
'AZE': 'AZ',
'BAH': 'BS',
'BAN': 'BD',
'BAR': 'BB',
'BDI': 'BI',
'BEL': 'BE',
'BEN': 'BJ',
'BER': 'BM',
'BHU': 'BT',
'BIH': 'BA',
'BIZ': 'BZ',
'BLR': 'BY',
'BOL': 'BO',
'BOT': 'BW',
'BRA': 'BR',
'BRN': 'BH',
'BRU': 'BN',
'BUL': 'BG',
'BUR': 'BF',
'CAF': 'CF',
'CAM': 'KH',
'CAN': 'CA',
'CAY': 'KY',
'CGO': 'CG',
'CHA': 'TD',
'CHI': 'CL',
'CHN': 'CN',
'CIV': 'CI',
'CMR': 'CM',
'COD': 'CD',
'COK': 'CK',
'COL': 'CO',
'COM': 'KM',
'CPV': 'CV',
'CRC': 'CR',
'CRO': 'HR',
'CUB': 'CU',
'CYP': 'CY',
'CZE': 'CZ',
'DEN': 'DK',
'DJI': 'DJ',
'DMA': 'DM',
'DOM': 'DO',
'ECU': 'EC',
'EGY': 'EG',
'ERI': 'ER',
'ESA': 'SV',
'ESP': 'ES',
'EST': 'EE',
'ETH': 'ET',
'FIJ': 'FJ',
'FIN': 'FI',
'FRA': 'FR',
'FSM': 'FM',
'GAB': 'GA',
'GAM': 'GM',
'GBR': 'GB',
'GBS': 'GW',
'GEO': 'GE',
'GEQ': 'GQ',
'GER': 'DE',
'GHA': 'GH',
'GRE': 'GR',
'GRN': 'GD',
'GUA': 'GT',
'GUI': 'GN',
'GUM': 'GU',
'GUY': 'GY',
'HAI': 'HT',
'HKG': 'HK',
'HON': 'HN',
'HUN': 'HU',
'INA': 'ID',
'IND': 'IN',
'IRI': 'IR',
'IRL': 'IE',
'IRQ': 'IQ',
'ISL': 'IS',
'ISR': 'IL',
'ISV': 'VI',
'ITA': 'IT',
'IVB': 'VG',
'JAM': 'JM',
'JOR': 'JO',
'JPN': 'JP',
'KAZ': 'KZ',
'KEN': 'KE',
'KGZ': 'KG',
'KIR': 'KI',
'KOR': 'KR',
'KSA': 'SA',
'KUW': 'KW',
'LAO': 'LA',
'LAT': 'LV',
'LBA': 'LY',
'LBR': 'LR',
'LCA': 'LC',
'LES': 'LS',
'LIB': 'LB',
'LIE': 'LI',
'LTU': 'LT',
'LUX': 'LU',
'MAD': 'MG',
'MAR': 'MA',
'MAS': 'MY',
'MAW': 'MW',
'MDA': 'MD',
'MDV': 'MV',
'MEX': 'MX',
'MGL': 'MN',
'MHL': 'MH',
'MKD': 'MK',
'MLI': 'ML',
'MLT': 'MT',
'MNE': 'ME',
'MON': 'MC',
'MOZ': 'MZ',
'MRI': 'MU',
'MTN': 'MR',
'MYA': 'MM',
'NAM': 'NA',
'NCA': 'NI',
'NED': 'NL',
'NEP': 'NP',
'NGR': 'NG',
'NIG': 'NE',
'NOR': 'NO',
'NRU': 'NR',
'NZL': 'NZ',
'OMA': 'OM',
'PAK': 'PK',
'PAN': 'PA',
'PAR': 'PY',
'PER': 'PE',
'PHI': 'PH',
'PLE': 'PS',
'PLW': 'PW',
'PNG': 'PG',
'POL': 'PL',
'POR': 'PT',
'PRK': 'KP',
'PUR': 'PR',
'QAT': 'QA',
'ROU': 'RO',
'RSA': 'ZA',
'RUS': 'RU',
'RWA': 'RW',
'SAM': 'WS',
'SEN': 'SN',
'SEY': 'SC',
'SIN': 'SG',
'SKN': 'KN',
'SLE': 'SL',
'SLO': 'SI',
'SMR': 'SM',
'SOL': 'SB',
'SOM': 'SO',
'SRB': 'RS',
'SRI': 'LK',
'STP': 'ST',
'SUD': 'SD',
'SUI': 'CH',
'SUR': 'SR',
'SVK': 'SK',
'SWE': 'SE',
'SWZ': 'SZ',
'SYR': 'SY',
'TAN': 'TZ',
'TGA': 'TO',
'THA': 'TH',
'TJK': 'TJ',
'TKM': 'TM',
'TLS': 'TL',
'TOG': 'TG',
'TPE': 'TW',
'TTO': 'TT',
'TUN': 'TN',
'TUR': 'TR',
'TUV': 'TV',
'UAE': 'AE',
'UGA': 'UG',
'UKR': 'UA',
'URU': 'UY',
'USA': 'US',
'UZB': 'UZ',
'VAN': 'VU',
'VEN': 'VE',
'VIE': 'VN',
'VIN': 'VC',
'YEM': 'YE',
'ZAM': 'ZM',
'ZIM': 'ZW',
}
ISO_TO_IOC = dict((iso, ioc) for ioc, iso in IOC_TO_ISO.items())
def check_ioc_countries(verbosity=1):
"""
Check if all IOC codes map to ISO codes correctly
"""
from django_countries.data import COUNTRIES
if verbosity: # pragma: no cover
print("Checking if all IOC codes map correctly")
for key in ISO_TO_IOC:
assert COUNTRIES.get(key), 'No ISO code for %s' % key
if verbosity: # pragma: no cover
print("Finished checking IOC codes")
django-countries-3.4.1/django_countries/templatetags/ 0000775 0001750 0001750 00000000000 12612051266 023266 5 ustar chris chris 0000000 0000000 django-countries-3.4.1/django_countries/templatetags/countries.py 0000664 0001750 0001750 00000000270 12572211635 025655 0 ustar chris chris 0000000 0000000 from django import template
from django_countries.fields import Country
register = template.Library()
@register.assignment_tag
def get_country(code):
return Country(code=code)
django-countries-3.4.1/django_countries/templatetags/__init__.py 0000664 0001750 0001750 00000000000 12572211635 025370 0 ustar chris chris 0000000 0000000 django-countries-3.4.1/django_countries/conf.py 0000664 0001750 0001750 00000004776 12475430413 022113 0 ustar chris chris 0000000 0000000 import django.conf
class AppSettings(django.conf.BaseSettings):
"""
A holder for app-specific default settings that allows overriding via
the project's settings.
"""
def __getattribute__(self, attr):
if attr == attr.upper():
try:
return getattr(django.conf.settings, attr)
except AttributeError:
pass
return super(AppSettings, self).__getattribute__(attr)
class Settings(AppSettings):
COUNTRIES_FLAG_URL = 'flags/{code}.gif'
"""
The URL for a flag.
It can either be relative to the static url, or an absolute url.
The location is parsed using Python's string formatting and is passed the
following arguments:
* code
* code_upper
For example: ``COUNTRIES_FLAG_URL = 'flags/16x10/{code_upper}.png'``
"""
COUNTRIES_COMMON_NAMES = True
"""
Whether to use the common names for some countries, as opposed to the
official ISO name.
Some examples:
"Bolivia" instead of "Bolivia, Plurinational State of"
"South Korea" instead of "Korea (the Republic of)"
"Taiwan" instead of "Taiwan (Province of China)"
"""
COUNTRIES_OVERRIDE = {}
"""
A dictionary of names to override the defaults.
Note that you will need to handle translation of customised country names.
Setting a country's name to ``None`` will exclude it from the country list.
For example::
COUNTRIES_OVERRIDE = {
'NZ': _('Middle Earth'),
'AU': None
}
"""
COUNTRIES_ONLY = {}
"""
Similar to COUNTRIES_OVERRIDE
A dictionary of names to include in selection.
Note that you will need to handle translation of customised country names.
For example::
COUNTRIES_ONLY = {
'NZ': _('Middle Earth'),
'AU': _('Desert'),
}
"""
COUNTRIES_FIRST = []
"""
Countries matching the country codes provided in this list will be shown
first in the countries list (in the order specified) before all the
alphanumerically sorted countries.
"""
COUNTRIES_FIRST_REPEAT = False
"""
Countries listed in :attr:`COUNTRIES_FIRST` will be repeated again in the
alphanumerically sorted list if set to ``True``.
"""
COUNTRIES_FIRST_BREAK = None
"""
Countries listed in :attr:`COUNTRIES_FIRST` will be followed by a null
choice with this title (if set) before all the alphanumerically sorted
countries.
"""
settings = Settings()
django-countries-3.4.1/django_countries/tests/ 0000775 0001750 0001750 00000000000 12612051266 021736 5 ustar chris chris 0000000 0000000 django-countries-3.4.1/django_countries/tests/settings_lts.py 0000664 0001750 0001750 00000000230 12475430413 025027 0 ustar chris chris 0000000 0000000 """
Allow Django 1.4 to use the same test discovery runner method.
"""
from .settings import * # NOQA
TEST_RUNNER = 'discover_runner.DiscoverRunner'
django-countries-3.4.1/django_countries/tests/settings.py 0000664 0001750 0001750 00000000505 12475430413 024152 0 ustar chris chris 0000000 0000000 SECRET_KEY = 'test'
INSTALLED_APPS = (
'django_countries',
'django_countries.tests',
)
DATABASES = {
'default': {'ENGINE': 'django.db.backends.sqlite3'}
}
STATIC_URL = '/static-assets/'
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
)
django-countries-3.4.1/django_countries/tests/test_tags.py 0000664 0001750 0001750 00000002171 12572211635 024311 0 ustar chris chris 0000000 0000000 from django.template import Template, Context
from django.test import TestCase
from django.utils import translation
class TestCountriesTags(TestCase):
TEMPLATE_COUNTRY = Template(
"{% load countries %}{% get_country code as country %}{{ country }}")
TEMPLATE_NAME = Template(
"{% load countries %}{% get_country code as country %}"
"{{ country.name }}")
def test_country(self):
rendered = self.TEMPLATE_COUNTRY.render(Context({'code': 'BR'}))
self.assertEqual(rendered, 'BR')
def test_country_name(self):
rendered = self.TEMPLATE_NAME.render(Context({'code': 'BR'}))
self.assertEqual(rendered, 'Brazil')
def test_country_name_translated(self):
with translation.override('pt-BR'):
rendered = self.TEMPLATE_NAME.render(Context({'code': 'BR'}))
self.assertEqual(rendered, 'Brasil')
def test_wrong_code(self):
rendered = self.TEMPLATE_COUNTRY.render(Context({'code': 'XX'}))
self.assertEqual(rendered, 'XX')
rendered = self.TEMPLATE_NAME.render(Context({'code': 'XX'}))
self.assertEqual(rendered, '')
django-countries-3.4.1/django_countries/tests/test_fields.py 0000664 0001750 0001750 00000024207 12612047442 024623 0 ustar chris chris 0000000 0000000 # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import django
from django.forms import Select
from django.forms.models import modelform_factory
from django.test import TestCase
from django.utils import translation
from django.utils.encoding import force_text
try:
from unittest import skipIf
except ImportError:
from django.utils.unittest import skipIf
from django_countries import fields, countries
from django_countries.tests import forms, custom_countries
from django_countries.tests.models import Person, AllowNull, en_zed
skipUnlessLegacy = skipIf(
django.VERSION >= (1, 5),
"Legacy tests only necessary in Django < 1.5")
class TestCountryField(TestCase):
def test_logic(self):
person = Person(name='Chris Beaven', country='NZ')
self.assertEqual(person.country, 'NZ')
self.assertNotEqual(person.country, 'ZZ')
self.assertTrue(person.country)
person.country = ''
self.assertFalse(person.country)
def test_only_from_instance(self):
self.assertRaises(AttributeError, lambda: Person.country)
@skipIf(
django.VERSION < (1, 7), "Field.deconstruct introduced in Django 1.7")
def test_deconstruct(self):
field = Person._meta.get_field('country')
self.assertEqual(
field.deconstruct(),
('country', 'django_countries.fields.CountryField', [],
{'max_length': 2}))
def test_text(self):
person = Person(name='Chris Beaven', country='NZ')
self.assertEqual(force_text(person.country), 'NZ')
def test_name(self):
person = Person(name='Chris Beaven', country='NZ')
self.assertEqual(person.country.name, 'New Zealand')
def test_flag(self):
person = Person(name='Chris Beaven', country='NZ')
with self.settings(STATIC_URL='/static-assets/'):
self.assertEqual(
person.country.flag, '/static-assets/flags/nz.gif')
def test_custom_field_flag_url(self):
person = Person(name='Chris Beaven', country='NZ', other_country='US')
self.assertEqual(
person.other_country.flag, '//flags.example.com/us.gif')
def test_COUNTRIES_FLAG_URL_setting(self):
# Custom relative url
person = Person(name='Chris Beaven', country='NZ')
with self.settings(COUNTRIES_FLAG_URL='img/flag-{code_upper}.png',
STATIC_URL='/static-assets/'):
self.assertEqual(
person.country.flag, '/static-assets/img/flag-NZ.png')
# Custom absolute url
with self.settings(COUNTRIES_FLAG_URL='https://flags.example.com/'
'{code_upper}.PNG'):
self.assertEqual(
person.country.flag, 'https://flags.example.com/NZ.PNG')
def test_blank(self):
person = Person.objects.create(name='The Outsider')
self.assertEqual(person.country.code, '')
person = Person.objects.get(pk=person.pk)
self.assertEqual(person.country.code, '')
def test_null(self):
person = AllowNull.objects.create(country=None)
self.assertIsNone(person.country.code)
person = AllowNull.objects.get(pk=person.pk)
self.assertIsNone(person.country.code)
def test_len(self):
person = Person(name='Chris Beaven', country='NZ')
self.assertEqual(len(person.country), 2)
person = Person(name='The Outsider', country=None)
self.assertEqual(len(person.country), 0)
def test_lookup_text(self):
Person.objects.create(name='Chris Beaven', country='NZ')
Person.objects.create(name='Pavlova', country='NZ')
Person.objects.create(name='Killer everything', country='AU')
lookup = Person.objects.filter(country='NZ')
names = lookup.order_by('name').values_list('name', flat=True)
self.assertEqual(list(names), ['Chris Beaven', 'Pavlova'])
def test_lookup_country(self):
Person.objects.create(name='Chris Beaven', country='NZ')
Person.objects.create(name='Pavlova', country='NZ')
Person.objects.create(name='Killer everything', country='AU')
oz = fields.Country(code='AU', flag_url='')
lookup = Person.objects.filter(country=oz)
names = lookup.values_list('name', flat=True)
self.assertEqual(list(names), ['Killer everything'])
def test_save_empty_country(self):
Person.objects.create(name='The Outsider')
person = Person.objects.get()
self.assertEqual(person.country.code, '')
def test_create_modelform(self):
Form = modelform_factory(Person, fields=['country'])
form_field = Form().fields['country']
self.assertTrue(isinstance(form_field.widget, Select))
def test_render_form(self):
Form = modelform_factory(Person, fields=['country'])
Form().as_p()
def test_custom_country(self):
self.assertEqual(
list(Person._meta.get_field('fantasy_countries').choices),
[('NV', 'Neverland'), ('NZ', 'New Zealand')])
@skipIf(
django.VERSION < (1, 7), "Field.deconstruct introduced in Django 1.7")
def test_custom_country_deconstruct(self):
field = Person._meta.get_field('fantasy_countries')
self.assertEqual(
field.deconstruct(),
(
'fantasy_countries',
'django_countries.fields.CountryField',
[],
{
'countries': custom_countries.FantasyCountries,
'max_length': 2
}
))
class TestCountryObject(TestCase):
def test_hash(self):
country = fields.Country(code='XX', flag_url='')
self.assertEqual(hash(country), hash('XX'))
def test_repr(self):
country1 = fields.Country(code='XX')
country2 = fields.Country(code='XX', flag_url='')
country3 = fields.Country(code='XX', str_attr='name')
self.assertEqual(
repr(country1),
'Country(code={0})'.format(repr('XX')))
self.assertEqual(
repr(country2),
'Country(code={0}, flag_url={1})'.format(repr('XX'), repr('')))
self.assertEqual(
repr(country3),
'Country(code={0}, str_attr={1})'.format(repr('XX'), repr('name')))
def test_str(self):
country = fields.Country(code='NZ')
self.assertEqual('%s' % country, 'NZ')
def test_str_attr(self):
country = fields.Country(code='NZ', str_attr='name')
self.assertEqual('%s' % country, 'New Zealand')
def test_flag_on_empty_code(self):
country = fields.Country(code='', flag_url='')
self.assertEqual(country.flag, '')
def test_ioc_code(self):
country = fields.Country(code='NL', flag_url='')
self.assertEqual(country.ioc_code, 'NED')
def test_country_from_ioc_code(self):
country = fields.Country.country_from_ioc('NED')
self.assertEqual(country, fields.Country('NL', flag_url=''))
def test_country_from_blank_ioc_code(self):
country = fields.Country.country_from_ioc('')
self.assertIsNone(country)
def test_country_from_nonexistence_ioc_code(self):
country = fields.Country.country_from_ioc('XXX')
self.assertIsNone(country)
def test_alpha3(self):
country = fields.Country(code='BN')
self.assertEqual(country.alpha3, 'BRN')
def test_alpha3_invalid(self):
country = fields.Country(code='XX')
self.assertEqual(country.alpha3, '')
def test_numeric(self):
country = fields.Country(code='BN')
self.assertEqual(country.numeric, 96)
def test_numeric_padded(self):
country = fields.Country(code='AL')
self.assertEqual(country.numeric_padded, '008')
country = fields.Country(code='BN')
self.assertEqual(country.numeric_padded, '096')
country = fields.Country(code='NZ')
self.assertEqual(country.numeric_padded, '554')
def test_numeric_invalid(self):
country = fields.Country(code='XX')
self.assertEqual(country.numeric, None)
def test_numeric_padded_invalid(self):
country = fields.Country(code='XX')
self.assertEqual(country.numeric_padded, None)
def test_empty_flag_url(self):
country = fields.Country(code='XX', flag_url='')
self.assertEqual(country.flag, '')
class TestModelForm(TestCase):
def test_translated_choices(self):
lang = translation.get_language()
translation.activate('eo')
form = forms.PersonForm()
try:
# This is just to prove that the language changed.
self.assertEqual(list(countries)[0][1], 'Afganio')
# If the choices aren't lazy, this wouldn't be translated. It's the
# second choice because the first one is the initial blank option.
self.assertEqual(
form.fields['country'].choices[1][1], 'Afganio')
self.assertEqual(
form.fields['country'].widget.choices[1][1], 'Afganio')
finally:
translation.activate(lang)
def test_blank_choice(self):
form = forms.PersonForm()
self.assertEqual(form.fields['country'].choices[0], ('', '---------'))
def test_no_blank_choice(self):
form = forms.PersonForm()
self.assertEqual(
form.fields['favourite_country'].choices[0], ('AF', 'Afghanistan'))
def test_blank_choice_label(self):
form = forms.AllowNullForm()
self.assertEqual(
form.fields['country'].choices[0], ('', '(select country)'))
@skipUnlessLegacy
def test_legacy_default(self):
self.assertEqual(
forms.LegacyForm.base_fields['default'].initial, 'AU')
@skipUnlessLegacy
def test_legacy_default_callable(self):
self.assertEqual(
forms.LegacyForm.base_fields['default_callable'].initial, en_zed)
form = forms.LegacyForm()
self.assertEqual(form['default_callable'].value(), 'NZ')
@skipUnlessLegacy
def test_legacy_empty_value(self):
self.assertEqual(
forms.LegacyForm.base_fields['default'].empty_value, None)
self.assertEqual(
forms.LegacyForm.base_fields['default_callable'].empty_value, '')
django-countries-3.4.1/django_countries/tests/test_widgets.py 0000664 0001750 0001750 00000004157 12475430413 025026 0 ustar chris chris 0000000 0000000 from __future__ import unicode_literals
try:
from urllib import parse as urlparse
except ImportError:
import urlparse # Python 2
from django.forms.models import modelform_factory
from django.test import TestCase
from django.utils import safestring
from django.utils.html import escape
from django_countries import widgets, countries, fields
from django_countries.conf import settings
from django_countries.tests.models import Person
class TestCountrySelectWidget(TestCase):
def setUp(self):
del countries.countries
self.Form = modelform_factory(
Person, fields=['country'],
widgets={'country': widgets.CountrySelectWidget})
def tearDown(self):
del countries.countries
def test_not_default_widget(self):
Form = modelform_factory(Person, fields=['country'])
widget = Form().fields['country'].widget
self.assertFalse(isinstance(widget, widgets.CountrySelectWidget))
def test_render_contains_flag_url(self):
with self.settings(COUNTRIES_ONLY={'AU': 'Desert'}):
html = self.Form().as_p()
self.assertIn(escape(urlparse.urljoin(
settings.STATIC_URL, settings.COUNTRIES_FLAG_URL)), html)
def test_render(self):
with self.settings(COUNTRIES_ONLY={'AU': 'Desert'}):
html = self.Form().as_p()
self.assertIn(fields.Country('__').flag, html)
self.assertNotIn(fields.Country('AU').flag, html)
def test_render_initial(self):
with self.settings(COUNTRIES_ONLY={'AU': 'Desert'}):
html = self.Form(initial={'country': 'AU'}).as_p()
self.assertIn(fields.Country('AU').flag, html)
self.assertNotIn(fields.Country('__').flag, html)
def test_render_escaping(self):
output = widgets.CountrySelectWidget().render('test', '