{ "info": { "author": "Ben Dowling", "author_email": "ben.m.dowling@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Topic :: Internet :: WWW/HTTP", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "# django-cities\n\n## Place models and worldwide place data for Django\n\n[![PyPI version](https://badge.fury.io/py/django-cities.svg)](https://badge.fury.io/py/django-cities) [![Build status](https://travis-ci.org/coderholic/django-cities.svg?branch=master)](https://travis-ci.org/coderholic/django-cities.svg?branch=master)\n\n----\n\ndjango-cities provides you with place related models (eg. Country, Region, City) and data (from [GeoNames](http://www.geonames.org/)) that can be used in your django projects.\n\nThis package officially supports all currently supported versions of Python/Django:\n\n| Python | 2.7 | 3.3 | 3.4 | 3.5 | 3.6 |\n| :------------ | --- | --- | --- | --- | --- |\n| Django 1.7 | :x: | :x: | :x: | :x: | :x: |\n| Django 1.8 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :large_blue_circle: |\n| Django 1.9 | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :large_blue_circle: |\n| Django 1.10 | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :large_blue_circle: |\n| Django 1.11 | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: |\n| Django 2.0 | :x: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: |\n| Django [master](https://github.com/django/django/archive/master.tar.gz) | :x: | :x: | :x: | :x: | :x: |\n\n| Key | |\n| :-: | :------------------------------------------------------------------ |\n| :white_check_mark: | Officially supported, tested, and passing |\n| :large_blue_circle: | Tested and passing, but not officially supported |\n| :white_square_button: | Not officially supported, may break at any time, most tests passing |\n| :x: | Known incompatibilities |\n\nAuthored by [Ben Dowling](http://www.coderholic.com), and some great [contributors](https://github.com/coderholic/django-cities/contributors).\n\nSee some of the data in action at [city.io](http://city.io) and [country.io](http://country.io).\n\n----\n\n* [Requirements](#requirements)\n* [Installation](#installation)\n* [Configuration](#configuration)\n * [Migration Configuration](#migration-configuration)\n * [Swappable Models](#swappable-models)\n * [Alternative Name Types](#alternative-name-types)\n * [Continent Data](#continent-data)\n * [Run Migrations](#run-migrations)\n * [Import Configuration](#import-configuration)\n * [Download Directory](#download-directory)\n * [Download Files](#download-files)\n * [Currency Data](#currency-data)\n * [Countries That No Longer Exist](#countries-that-no-longer-exist)\n * [Postal Code Validation](#postal-code-validation)\n * [Custom `slugify()` function](#custom-slugify-function)\n * [Cities Without Regions](#cities-without-regions)\n * [Languages/Locales To Import](#languageslocales-to-import)\n * [Limit Imported Postal Codes](#limit-imported-postal-codes)\n * [Plugins](#plugins)\n * [Import Data](#import-data)\n* [Writing Plugins](#writing-plugins)\n* [Examples](#examples)\n* [Third Party Apps/Extensions](#third-party-apps--extensions)\n* [TODO](#todo)\n* [Notes](#notes)\n* [Running Tests](#running-tests)\n* [Release Notes](#release-notes)\n\n----\n\n## Requirements\n\nYour database must support spatial queries, see the [GeoDjango documentation](https://docs.djangoproject.com/en/dev/ref/contrib/gis/) for details and setup instructions.\n\n\n\n## Installation\n\nClone this repository into your project:\n\n```bash\ngit clone https://github.com/coderholic/django-cities.git\n```\n\nDownload the zip file and unpack it:\n\n```bash\nwget https://github.com/coderholic/django-cities/archive/master.zip\nunzip master.zip\n```\n\nInstall with pip:\n\n```bash\npip install django-cities\n```\n\n\n\n## Configuration\n\nYou'll need to enable GeoDjango. See that [documentation](https://docs.djangoproject.com/en/1.10/ref/contrib/gis/tutorial/#setting-up) for guidance.\n\nYou'll need to add `cities` to `INSTALLED_APPS` in your projects `settings.py` file:\n\n```python\nINSTALLED_APPS = (\n # ...\n 'cities',\n # ...\n)\n```\n\n### Migration Configuration\n\nThese settings should be reviewed and set or modified BEFORE any migrations have been run.\n\n#### Swappable Models\n\nSome users may wish to override some of the default models to add data, override default model methods, or add custom managers. This project supports swapping models out using the [django-swappable-models project](https://github.com/wq/django-swappable-models).\n\nTo swap models out, first define your own custom model in your custom cities app. You will need to subclass the appropriate base model from `cities.models`:\n\nHere's an example `my_cities_app/models.py`:\n\n```python\nfrom django.db import models\n\nfrom cities.models import BaseCountry\n\n\nclass CustomCountryModel(BaseCountry, models.Model):\n more_data = models.TextField()\n\n class Meta(BaseCountry.Meta):\n pass\n```\n\nThen you will need to configure your project by setting the appropriate option:\n\n| Model | Setting Name | Default Value |\n| :-------- | :----------------------- | :----------------- |\n| Continent | `CITIES_CONTINENT_MODEL` | `cities.Continent` |\n| Country | `CITIES_COUNTRY_MODEL` | `cities.Country` |\n| City | `CITIES_CITY_MODEL` | `cities.City` |\n\nSo to use the `CustomCountryModel` we defined above, we would add the dotted **model** string to our project's `settings.py`:\n\n```python\n# ...\n\nCITIES_COUNTRY_MODEL = 'my_cities_app.CustomCountryModel'\n\n# ...\n```\n\nThe dotted model string is simply the dotted import path with the `.models` substring removed, just `.`.\n\nOnce you have set the option in your `settings.py`, all appropriate foreign keys in django-cities will point to your custom model. So in the above example, the foreign keys `Region.country`, `City.country`, and `PostalCode.country` will all automatically point to the `CustomCountryModel`. This means that you do NOT need to customize any dependent models if you don't want to.\n\n#### Alternative Name Types\n\nThe Geonames data for alternative names contain additional information, such as links to external websites (mostly Wikipedia articles) and pronunciation guides (pinyin). However, django-cities only uses and imports a subset of those types. Since some users may wish to use them all, the `CITIES_ALTERNATIVE_NAME_TYPES` and `CITIES_AIRPORT_TYPES` settings can be used to define the alternative name types in the database.\n\nThese settings should be specified as a tuple of tuple choices:\n\n```python\nCITIES_AIRPORT_TYPES = (\n ('iata', _(\"IATA (Airport) Code\")),\n ('icao', _(\"ICAO (Airport) Code\")),\n ('faac', _(\"FAAC (Airport) Code\")),\n)\n\nCITIES_ALTERNATIVE_NAME_TYPES = (\n ('name', _(\"Name\")),\n ('abbr', _(\"Abbreviation\")),\n ('link', _(\"Link\")),\n)\n```\n\nIf `CITIES_INCLUDE_AIRPORT_CODES` is set to `True`, the choices in `CITIES_AIRPORT_TYPES` will be appended to the `CITIES_ALTERNATIVE_NAME_TYPES` choices. Otherwise, no airport types are imported.\n\nThe Geonames data also contains alternative names that are purely numeric.\n\nThe `CITIES_INCLUDE_NUMERIC_ALTERNATIVE_NAMES` setting controls whether or not purely numeric alternative names are imported. Set to `True` to import them, and to `False` to skip them.\n\n#### Continent Data\n\nSince continent data rarely (if ever) changes, the continent data is loaded directly from Python data structures included with the django-cities distribution. However, there are different continent models with different numbers of continents. Therefore, some users may wish to override the default settings by setting the `CITIES_CONTINENT_DATA` to a Python dictionary where the keys are the continent code and the values are (name, geonameid) tuples.\n\nFor an overview of different continent models, please see the Wikipedia article on Continents:\n\nhttps://en.wikipedia.org/wiki/Continent#Number\n\nThe following is the default continent data in [`cities/conf.py`](https://github.com/coderholic/django-cities/blob/master/cities/conf.py#L178):\n\n```python\nCITIES_CONTINENT_DATA = {\n 'AF': ('Africa', 6255146),\n 'AS': ('Asia', 6255147),\n 'EU': ('Europe', 6255148),\n 'NA': ('North America', 6255149),\n 'OC': ('Oceania', 6255151),\n 'SA': ('South America', 6255150),\n 'AN': ('Antarctica', 6255152),\n}\n```\n\nNote that if you do not use these default settings, you will need to register a plugin with a `country_pre` method to adjust the continent ID for country models before countries are processed and saved to the database by the import script. Please contribute your plugin back upstream to this project so that others may benefit from your work by creating a pull request containing your plugin and any relevant documentation for it.\n\n### Run Migrations\n\nAfter you have configured all migration settings, run\n\n```bash\npython manage.py migrate cities\n```\n\nto create the required database tables and add the continent data to its table.\n\n\n\n### Import Configuration\n\nThese settings should also be reviewed and set or modified before importing any data. Changing these settings after importing data may not have the intended effect.\n\n#### Download Directory\n\nSpecify a download directory (used to specify a writable directory).\n\nDefault: `cities/data`\n\nYou may want to use this if you are on a cloud services provider, or if django-cities is installed on a read-only medium.\n\nNote that this path must be an absolute path.\n\n```python\nCITIES_DATA_DIR = '/var/data'\n```\n\n#### Download Files\n\nYou can override the files the import command uses to process data:\n\n```python\nCITIES_FILES = {\n # ...\n 'city': {\n 'filename': 'cities1000.zip',\n 'urls': ['http://download.geonames.org/export/dump/'+'{filename}']\n },\n # ...\n}\n```\n\nIt is also possible to specify multiple filenames to process. Note that these files are processed in the order they are specified, so duplicate data in files specified later in the list will overwrite data from files specified earlier in the list.\n\n```python\nCITIES_FILES = {\n # ...\n 'city': {\n 'filenames': [\"US.zip\", \"GB.zip\", ],\n 'urls': ['http://download.geonames.org/export/dump/'+'{filename}']\n },\n # ...\n}\n```\n\nNote that you do not need to specify all keys in the `CITIES_FILES` dictionary. Any keys you do not specify will use their default values as defined in [`cities/conf.py`](https://github.com/coderholic/django-cities/blob/master/cities/conf.py#L26).\n\n#### Currency Data\n\nThe Geonames data includes currency data, but it is limited to the currency code (example: \"USD\") and the currency name (example: \"Dollar\"). The django-cities package offers the ability to import currency symbols (example: \"$\") with the country model.\n\nHowever, like the continent data, since this rarely changes, the currency symbols are loaded directly from Python data structures included with the django-cities distribution in the `CITIES_CURRENCY_SYMBOLS` setting. Users can override this setting if they wish to add or modify the imported currency symbols.\n\nFor default values see the included [`cities/conf.py` file](https://github.com/coderholic/django-cities/blob/master/cities/conf.py#L189).\n\n```python\nCITIES_CURRENCY_SYMBOLS = {\n \"AED\": \"\u062f.\u0625\", \"AFN\": \"\u060b\", \"ALL\": \"L\", \"AMD\": \"\u0564\u0580.\", \"ANG\": \"\u0192\", \"AOA\": \"Kz\",\n \"ARS\": \"$\", \"AUD\": \"$\", \"AWG\": \"\u0192\", \"AZN\": \"m\",\n \"BAM\": \"KM\", \"BBD\": \"$\", \"BDT\": \"\u09f3\", \"BGN\": \"\u043b\u0432\", \"BHD\": \"\u0628.\u062f\", \"BIF\": \"Fr\",\n # ...\n \"UAH\": \"\u20b4\", \"UGX\": \"Sh\", \"USD\": \"$\", \"UYU\": \"$\", \"UZS\": \"\u043b\u0432\",\n```\n\n#### Countries That No Longer Exist\n\nThe Geonames data includes countries that no longer exist. At this time, those countries are the Dutch Antilles (`AN`) and Serbia and Montenegro (`CS`). If you wish to import those countries, set the `CITIES_NO_LONGER_EXISTENT_COUNTRY_CODES` to an empty list (`[]`).\n\nDefault: `['CS', 'AN']`\n\n```python\nCITIES_NO_LONGER_EXISTENT_COUNTRY_CODES = ['CS', 'AN']\n```\n\n#### Postal Code Validation\n\nThe Geonames data contains country postal code formats and regular expressions, as well as postal codes. Some of these postal codes do not match the regular expression of their country. Users who wish to ignore invalid postal codes when importing data can set the `CITIES_VALIDATE_POSTAL_CODES` setting to `True` to skip importing postal codes that do not validate the country postal code regular expression.\n\nIf you have regional knowledge of postal codes that do not validate, please either update the postal code itself or the country postal codes regular expression on the Geonames website. Doing this will help all Geonames users (including this project but also every other Geonames user).\n\n```python\nCITIES_VALIDATE_POSTAL_CODES = True\n```\n\n#### Custom `slugify()` Function\n\nYou may wish to customize the slugs generated by django-cities. To do so, you will need to write your own `slugify()` function and specify its dotted import path in the `CITIES_SLUGIFY_FUNCTION`:\n\n```python\nCITIES_SLUGIFY_FUNCTION = 'cities.util.default_slugify'\n```\n\nYour customized slugify function should accept two arguments: the object itself and the slug generated by the object itself. It should return the final slug as a string.\n\nBecause the slugify function contains code that would be reused by multiple objects, there is only a single slugify function for all of the objects in django-cities. To generate different slugs for different types of objects, test against the object's class name (`obj.__class__.__name__`).\n\nDefault slugify function (see [`cities/util.py`](https://github.com/coderholic/django-cities/tree/master/cities/util.py#L35)):\n\n```python\n# SLUGIFY REGEXES\n\nto_und_rgx = re.compile(r\"[']\", re.UNICODE)\nslugify_rgx = re.compile(r'[^-\\w._~]', re.UNICODE)\nmulti_dash_rgx = re.compile(r'-{2,}', re.UNICODE)\ndash_und_rgx = re.compile(r'[-_]_', re.UNICODE)\nund_dash_rgx = re.compile(r'[-_]-', re.UNICODE)\nstarting_chars_rgx = re.compile(r'^[-._]*', re.UNICODE)\nending_chars_rgx = re.compile(r'[-._]*$', re.UNICODE)\n\n\ndef default_slugify(obj, value):\n if value is None:\n return None\n\n value = force_text(unicode_func(value))\n value = unicodedata.normalize('NFKC', value.strip())\n value = re.sub(to_und_rgx, '_', value)\n value = re.sub(slugify_rgx, '-', value)\n value = re.sub(multi_dash_rgx, '-', value)\n value = re.sub(dash_und_rgx, '_', value)\n value = re.sub(und_dash_rgx, '_', value)\n value = re.sub(starting_chars_rgx, '', value)\n value = re.sub(ending_chars_rgx, '', value)\n return mark_safe(value)\n```\n\n#### Cities Without Regions\n\nNote: This used to be `CITIES_IGNORE_EMPTY_REGIONS`.\n\nSome cities in the Geonames data files do not have region information. By default, these cities are imported as normal (they still have foreign keys to their country), but if you wish to *avoid* importing these cities, set `CITIES_SKIP_CITIES_WITH_EMPTY_REGIONS` to `True`:\n\n```python\n# Import cities without region (default False)\nCITIES_SKIP_CITIES_WITH_EMPTY_REGIONS = True\n```\n\n#### Languages/Locales To Import\n\nLimit imported alternative names by languages/locales\n\nNote that many alternative names in the Geonames data do not specify a language code, so if you manually specify language codes and do not include `und`, you may not import as many alternative names as you want.\n\nSpecial values:\n\n* `ALL` - import all alternative names\n* `und` - alternative names that do not specify a language code. When imported, these alternative names will be assigned a language code of `und`. If this language code is not specified, alternative names that do not specify a language code are not imported.\n* `LANGUAGES` - a \"shortcut\" to import all alternative names specified in the `LANGUAGES` setting in your Django project's `settings.py`\n\nFor a full list of ISO639-1 language codes, see the [iso-languagecodes.txt](http://download.geonames.org/export/dump/iso-languagecodes.txt) file on Geonames.\n\n```python\nCITIES_LOCALES = ['en', 'und', 'LANGUAGES']\n```\n\n#### Limit Imported Postal Codes\n\nLimit the imported postal codes to specific countries\n\nSpecial value:\n\n* `ALL` - import all postal codes\n\n```python\nCITIES_POSTAL_CODES = ['US', 'CA']\n```\n\n#### Plugins\n\nYou can write your own plugins to process data before and after it is written to the database. See the section on [Writing Plugins](#writing-plugins) for details.\n\nTo activate plugins, you need to add their dotted import strings to the `CITIES_PLUGINS` option. This example activates the `postal_code_ca` and `reset_queries` plugins that come with django-cities:\n\n```python\nCITIES_PLUGINS = [\n # Canadian postal codes need region codes remapped to match geonames\n 'cities.plugin.postal_code_ca.Plugin',\n # Reduce memory usage when importing large datasets (e.g. \"allCountries.zip\")\n 'cities.plugin.reset_queries.Plugin',\n]\n```\n\nNote that some plugins may use their own configuration options:\n\n```python\n# This setting may be specified if you use 'cities.plugin.reset_queries.Plugin'\nCITIES_PLUGINS_RESET_QUERIES_CHANCE = 1.0 / 1000000\n```\n\n### Import Data\n\nAfter you have configured all import settings, run\n\n```bash\npython manage.py cities --import=all\n```\n\nto import all of the place data.\n\nYou may also import specific object types:\n\n```bash\npython manage.py cities --import=country\n```\n\n```bash\npython manage.py cities --import=city\n```\n\n**NOTE:** This can take a long time, although there are progress bars drawn in the terminal.\n\nSpecifically, importing postal codes can take one or two orders of magnitude more time than importing other objects.\n\n\n\n## Writing Plugins\n\nYou can write plugins that modify data before and after it is processed by the import script. For example, you can use this to adjust the continent a country belongs to, or you can use it to add or modify any additional data if you customize and override any django-cities models.\n\nA plugin is simply a Python class that has implemented one or more hook functions as members. Hooks can either modify data before it is processed by the import script, or modify the database after the object has been saved to the database by the import script. By raising `cities.conf.HookException`, plugins can skip one piece of data.\n\nHere's a table of all available hooks:\n\n| Model | Pre Hook Name | Post Hook Name |\n| ----------------- | ----------------- | ------------------ |\n| `Country` | `country_pre` | `country_post` |\n| `Region` | `region_pre` | `region_post` |\n| `Subregion` | `subregion_pre` | `subregion_post` |\n| `City` | `city_pre` | `city_post` |\n| `District` | `district_pre` | `district_post` |\n| `PostalCode` | `postal_code_pre` | `postal_code_post` |\n| `AlternativeName` | `alt_name_pre` | `alt_name_post` |\n\nThe argument signatures for `_pre` hooks and `_post` hooks differ. All `_pre` hooks have the following argument signature:\n\n```python\nclass ...Plugin(object):\n model_pre(self, parser, item)\n```\n\nwhereas all `_post` hooks also have the saved model instance available to them:\n\n```python\nclass ...Plugin(object):\n model_post(self, parser, _instance, item)\n```\n\nArguments passed to hooks:\n\n* `self` - the plugin object itself\n* `parser` - the instance of the `cities.Command` management command\n* `_instance` - instance of model that was created based on `item`\n* `item` - Python dictionary with data for row being processed\n\nNote that the argument names are simply conventions, you are free to rename them to whatever you wish as long as you keep their order.\n\nHere is a complete skeleton plugin class example:\n\n```python\nclass CompleteSkeletonPlugin(object):\n \"\"\"\n Skeleton plugin for django-cities that has hooks for all object types, and\n does not modify any import data or existing objects in the database.\n \"\"\"\n # Note: Only ONE of these methods needs to be defined. If a method is not\n # defined, the import command will avoid calling the undefined method.\n\n def country_pre(self, parser, imported_data_dict):\n pass\n\n def country_post(self, parser, country_instance, imported_data_dict):\n pass\n\n def region_pre(self, parser, imported_data_dict):\n pass\n\n def region_post(self, parser, region_instance, imported_data_dict):\n pass\n\n def subregion_pre(self, parser, imported_data_dict):\n pass\n\n def subregion_post(self, parser, subregion_instance, imported_data_dict):\n pass\n\n def city_pre(self, parser, imported_data_dict):\n pass\n\n def city_post(self, parser, city_instance, imported_data_dict):\n pass\n\n def district_pre(self, parser, imported_data_dict):\n pass\n\n def district_post(self, parser, district_instance, imported_data_dict):\n pass\n\n def alt_name_pre(self, parser, imported_data_dict):\n pass\n\n def alt_name_post(self, parser, alt_name_instance, imported_data_dict):\n pass\n\n def postal_code_pre(self, parser, imported_data_dict):\n pass\n\n def postal_code_post(self, parser, postal_code_instance, imported_data_dict):\n pass\n```\n\nSilly example:\n\n```python\nfrom cities.conf import HookException\n\nclass DorothyPlugin(object):\n \"\"\"\n This plugin skips importing cities that are not in Kansas, USA.\n \n There's no place like home.\n \"\"\"\n def city_pre(self, parser, import_dict):\n if import_dict['cc2'] == 'US' and import_dict['admin1Code'] != 'KS':\n raise HookException(\"Ignoring cities not in Kansas, USA\") # Raising a HookException skips importing the item\n else:\n # Modify the value of the data before it is written to the database\n import_dict['admin1Code'] = 'KS'\n\n def city_post(self, parser, city, import_data):\n # Checks if the region foreign key for the city database row is NULL\n if city.region is None:\n # Set it to Kansas\n city.region = Region.objects.get(country__code='US', code='KS')\n # Re-save any existing items that aren't in Kansas\n city.save()\n```\n\nOnce you have written a plugin, you will need to activate it by specifying its dotted import string in the `CITIES_PLUGINS` setting. See the [Plugins](#plugins) section for details.\n\n\n\n## Examples\n\nThis repository contains an example project which lets you browse the place hierarchy. See the [`example directory`](https://github.com/coderholic/django-cities/tree/master/example). Below are some small snippets to show you the kind of queries that are possible once you have imported data:\n\n\n```python\n# Find the 5 most populated countries in the World\n>>> Country.objects.order_by('-population')[:5]\n[, , ,\n , ]\n\n# Find what country the .ly TLD belongs to\n>>> Country.objects.get(tld='ly')\n\n\n# 5 Nearest cities to London\n>>> london = City.objects.filter(country__name='United Kingdom').get(name='London')\n>>> nearest = City.objects.distance(london.location).exclude(id=london.id).order_by('distance')[:5]\n\n# All cities in a state or county\n>>> City.objects.filter(country__code=\"US\", region__code=\"TX\")\n>>> City.objects.filter(country__name=\"United States\", subregion__name=\"Orange County\")\n\n# Get all countries in Japanese preferring official names if available,\n# fallback on ASCII names:\n>>> [country.alt_names_ja.get_preferred(default=country.name) for country in Country.objects.all()]\n\n# Alternate names for the US in English, Spanish and German\n>>> [x.name for x in Country.objects.get(code='US').alt_names.filter(language_code='de')]\n[u'USA', u'Vereinigte Staaten']\n>>> [x.name for x in Country.objects.get(code='US').alt_names.filter(language_code='es')]\n[u'Estados Unidos']\n>>> [x.name for x in Country.objects.get(code='US').alt_names.filter(language_code='en')]\n[u'United States of America', u'America', u'United States']\n\n# Alternative names for Vancouver, Canada\n>>> City.objects.get(name='Vancouver', country__code='CA').alt_names.all()\n[, ,\n , ,\n , ,\n , ,\n , ,\n , ,\n , ,\n , ,\n , ,\n , ,\n '...(remaining elements truncated)...']\n\n# Get zip codes near Mountain View, CA\n>>> PostalCode.objects.distance(City.objects.get(name='Mountain View', region__name='California').location).order_by('distance')[:5]\n[, , ,\n , ]\n```\n\n\n\n## Third-party Apps / Extensions\n\nThese are apps that build on top of the `django-cities`. Useful for essentially extending what `django-cities` can do.\n\n* [django-airports](https://github.com/bashu/django-airports) provides you with airport related model and data (from OpenFlights) that can be used in your Django projects.\n\n\n\n## TODO\n\nIn increasing order of difficulty:\n\n* Add tests for the plugins we ship with\n* Minimize number of attributes on abstract base models and adjust import script accordingly\n* Steal/modify all of the [contrib apps from django-contrib-light](https://github.com/yourlabs/django-cities-light/blob/stable/3.x.x/cities_light/contrib) (Django REST Framework integration, chained selects, and autocomplete)\n* Integrate [libpostal](https://github.com/openvenues/libpostal) to extract Country/City/District/Postal Code from an address string\n\n\n\n## Notes\n\nSome datasets are very large (> 100 MB) and take time to download/import.\n\nData will only be downloaded/imported if it is newer than your data, and only matching rows will be overwritten.\n\nThe cities manage command has options, see `--help`. Verbosity is controlled through the `LOGGING` setting.\n\n\n\n## Running Tests\n\n1. Install postgres, postgis and libgdal-dev\n2. Create `django_cities` database:\n\n sudo su -l postgres\n # Enter your password\n createuser -d -s -P some_username\n # Enter password\n createdb -T template0 -E utf-8 -l en_US.UTF-8 -O multitest django_cities\n psql -c 'create extension postgis;' -d django_cities\n\n3. Run tests:\n\n POSTGRES_USER=some_username POSTGRES_PASSWORD='password from createuser step' tox\n\n # If you have changed example data files then you should push your\n # changes to github and specify commit and repo variables:\n TRAVIS_COMMIT=`git rev-parse HEAD` TRAVIS_REPO_SLUG='github-username/django-cities' POSTGRES_USER=some_username POSTGRES_PASSWORD='password from createuser ste' tox\n\nAs an alternative to installing and running PostgreSQL system-wide,\nyou can run the tests against a transient Docker instance:\n\n```bash\ndocker run --rm -p 127.0.0.1:5432:5432 mdillon/postgis\n```\n\n### Useful test options:\n\n* `TRAVIS_LOG_LEVEL` - defaults to `INFO`, but set to `DEBUG` to see a (very) large and (very) complete log of the import script\n* `CITIES_FILES` - set the base urls to a `file://` path to use local files without modifying any other settings\n\n\n## Release Notes\n\n### 0.4.1\n\nUse Django's native migrations\n\n#### Upgrading from 0.4.1\n\nUpgrading from 0.4.1 is likely to cause problems trying to apply a migration when the tables already exist. In this case a fake migration needs to be applied:\n\n```bash\npython manage.py migrate cities 0001 --fake\n```\n\n### 0.4\n\n** **This release of django-cities is not backwards compatible with previous versions** **\n\nThe country model has some new fields:\n - elevation\n - area\n - currency\n - currency_name\n - languages\n - neighbours\n - capital\n - phone\n\nAlternative name support has been completely overhauled. The code and usage should now be much simpler. See the updated examples below.\n\nThe code field no longer contains the parent code. Eg. the code for California, US is now \"CA\". In the previous release it was \"US.CA\".\n\nThese changes mean that upgrading from a previous version isn't simple. All of the place IDs are the same though, so if you do want to upgrade it should be possible.", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/coderholic/django-cities", "keywords": "django cities countries regions postal codes geonames", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "django-cities", "package_url": "https://pypi.org/project/django-cities/", "platform": "", "project_url": "https://pypi.org/project/django-cities/", "project_urls": { "Homepage": "https://github.com/coderholic/django-cities" }, "release_url": "https://pypi.org/project/django-cities/0.5.0.6/", "requires_dist": null, "requires_python": "", "summary": "Place models and worldwide place data for Django", "version": "0.5.0.6" }, "last_serial": 3571285, "releases": { "0.2": [ { "comment_text": "", "digests": { "md5": "9ea6787b9399c860b71f44e424e4550d", "sha256": "c8b0ccd327c5d8ee88eb22db87c592d3b84551333bf48932c3e27863bef5552a" }, "downloads": -1, "filename": "django-cities-0.2.zip", "has_sig": false, "md5_digest": "9ea6787b9399c860b71f44e424e4550d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20703, "upload_time": "2012-04-05T17:11:53", "url": "https://files.pythonhosted.org/packages/c3/66/bb2b58d203176be9a914c8f9b91860201cea5614e1dafab70916c4456912/django-cities-0.2.zip" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "a87329c6181212d56b8bf0fead2ad51e", "sha256": "bb6aa72cd97376d2ee3c6de9162a1f267b786c88b2cb8ecf01b16300eae436e2" }, "downloads": -1, "filename": "django-cities-0.3.tar.gz", "has_sig": false, "md5_digest": "a87329c6181212d56b8bf0fead2ad51e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14291, "upload_time": "2014-02-25T05:02:32", "url": "https://files.pythonhosted.org/packages/42/f8/6631f97157c1bce0fd5503906f8e0d549930fe7f718bf3550176781f9293/django-cities-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "17a908312ec88a8944e160eca10da50a", "sha256": "c5ac370ba7998db33624b208199c3b2b4a255c14cc2ee55f9a5f8bc109c33d7e" }, "downloads": -1, "filename": "django-cities-0.4.tar.gz", "has_sig": false, "md5_digest": "17a908312ec88a8944e160eca10da50a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15548, "upload_time": "2014-06-19T20:00:48", "url": "https://files.pythonhosted.org/packages/4c/50/45f244861a38961ed6f79e9b795651e332cad6022b6563846abf942a3d83/django-cities-0.4.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "024bf0e9e9d699032cb14835f55c6cfd", "sha256": "dd8e83e30d8ee8888063219de98446968f27f19694d10033cd824b40db4c3847" }, "downloads": -1, "filename": "django-cities-0.4.1.tar.gz", "has_sig": false, "md5_digest": "024bf0e9e9d699032cb14835f55c6cfd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15534, "upload_time": "2014-07-05T21:05:58", "url": "https://files.pythonhosted.org/packages/b9/bf/801327d05fbe546b378dae4811448cd44d816e9c98c2509c49cc8618daab/django-cities-0.4.1.tar.gz" } ], "0.4.2": [ { "comment_text": "", "digests": { "md5": "b6e1234852c30b1c286af13b05a9b0bc", "sha256": "47a17b472233bca47c0ed80477df5e3e29f2787209b277539b5fd211e7f0621d" }, "downloads": -1, "filename": "django-cities-0.4.2.tar.gz", "has_sig": false, "md5_digest": "b6e1234852c30b1c286af13b05a9b0bc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20727, "upload_time": "2015-09-06T01:38:51", "url": "https://files.pythonhosted.org/packages/79/5e/3ca63dc4f36f829665d8edd309a55ad6fbc1290b64103083f031d6e5d3a4/django-cities-0.4.2.tar.gz" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "2ee43581f831aeaf425b99996b945bb6", "sha256": "c809eb8783895f351cf039b4c310fb3475895ba91be26cb282bf5c9f7100dd5a" }, "downloads": -1, "filename": "django-cities-0.5.tar.gz", "has_sig": false, "md5_digest": "2ee43581f831aeaf425b99996b945bb6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40303, "upload_time": "2016-12-27T13:05:58", "url": "https://files.pythonhosted.org/packages/9c/80/cdb3d3f45349ecb0373566665d7e80a72516ab3cff513433741f1af08e57/django-cities-0.5.tar.gz" } ], "0.5.0.1": [ { "comment_text": "", "digests": { "md5": "33d1eef2ebc8729d725d0ed745dd1aa1", "sha256": "7c933af0dbfe6eeda2ea2ee54bca1b725c50c7b77a2ff4fb61aa6a6780951aa2" }, "downloads": -1, "filename": "django-cities-0.5.0.1.tar.gz", "has_sig": false, "md5_digest": "33d1eef2ebc8729d725d0ed745dd1aa1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40602, "upload_time": "2016-12-27T15:28:28", "url": "https://files.pythonhosted.org/packages/d4/f3/051a3d40c82e859dd1fc4d3da9e6a92bdf06e59947c87f7246994731a6bc/django-cities-0.5.0.1.tar.gz" } ], "0.5.0.2": [ { "comment_text": "", "digests": { "md5": "4b4dce00edcf61508f27bd81c4622201", "sha256": "682e9d12dc8f7ab996f0f275f62b69231771a5da08b72848a13a5fe115d2deac" }, "downloads": -1, "filename": "django-cities-0.5.0.2.tar.gz", "has_sig": false, "md5_digest": "4b4dce00edcf61508f27bd81c4622201", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40725, "upload_time": "2017-01-20T07:12:33", "url": "https://files.pythonhosted.org/packages/01/fb/304d0a57ae956d1524ebce6eb04f3a78ce0f42074acc1edb10259df2f896/django-cities-0.5.0.2.tar.gz" } ], "0.5.0.3": [ { "comment_text": "", "digests": { "md5": "15762fa7ff9169349dbf3e85a990e514", "sha256": "f9fd1f1ee9d2aff597eeb00160bc769eeabb0155664b2dea7e24bedab0684f5e" }, "downloads": -1, "filename": "django-cities-0.5.0.3.tar.gz", "has_sig": false, "md5_digest": "15762fa7ff9169349dbf3e85a990e514", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40728, "upload_time": "2017-01-20T07:32:26", "url": "https://files.pythonhosted.org/packages/d9/17/9949f734cf72e74192caa2b81be1c5730d78f6e8236ad731353f4c66f618/django-cities-0.5.0.3.tar.gz" } ], "0.5.0.4": [ { "comment_text": "", "digests": { "md5": "9f3a81fdfe538ae92525884d725bc309", "sha256": "2afa09752e57996a0b8e0db71cbc2028d3543406017ffbdd8a243a84b2f7045a" }, "downloads": -1, "filename": "django-cities-0.5.0.4.tar.gz", "has_sig": true, "md5_digest": "9f3a81fdfe538ae92525884d725bc309", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 48807, "upload_time": "2017-03-08T10:11:09", "url": "https://files.pythonhosted.org/packages/63/d4/5d3da1c2ab77700a07815e70a1480def0290ba8536b4ab73e7f0f7d18f2e/django-cities-0.5.0.4.tar.gz" } ], "0.5.0.5": [ { "comment_text": "", "digests": { "md5": "a340ea8b8055950afcdea4fef32138fb", "sha256": "897cab1ff3821aa9b120cecbfcff01e8ddbd14e3fbb098b060316acc2b2e3499" }, "downloads": -1, "filename": "django-cities-0.5.0.5.tar.gz", "has_sig": true, "md5_digest": "a340ea8b8055950afcdea4fef32138fb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 49423, "upload_time": "2017-05-09T10:47:34", "url": "https://files.pythonhosted.org/packages/f7/0d/8918c7a386418d18c0c9b9a8ed6f87563a4978385def03de9e19ee039b9c/django-cities-0.5.0.5.tar.gz" } ], "0.5.0.6": [ { "comment_text": "", "digests": { "md5": "62295b19ab5c65dd0d7e50f8c60e982a", "sha256": "e4c537f04cea1b63485ef4f96e92104b17dbedba32666d9b12d585644502d957" }, "downloads": -1, "filename": "django-cities-0.5.0.6.tar.gz", "has_sig": true, "md5_digest": "62295b19ab5c65dd0d7e50f8c60e982a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 51122, "upload_time": "2018-02-11T03:37:48", "url": "https://files.pythonhosted.org/packages/a5/e6/2091da0499fc9ebc63496aa7efdaed492f9caaf4e5c7d15abcb85c7e16bb/django-cities-0.5.0.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "62295b19ab5c65dd0d7e50f8c60e982a", "sha256": "e4c537f04cea1b63485ef4f96e92104b17dbedba32666d9b12d585644502d957" }, "downloads": -1, "filename": "django-cities-0.5.0.6.tar.gz", "has_sig": true, "md5_digest": "62295b19ab5c65dd0d7e50f8c60e982a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 51122, "upload_time": "2018-02-11T03:37:48", "url": "https://files.pythonhosted.org/packages/a5/e6/2091da0499fc9ebc63496aa7efdaed492f9caaf4e5c7d15abcb85c7e16bb/django-cities-0.5.0.6.tar.gz" } ] }