Coder Social home page Coder Social logo

django-cities's Introduction

django-cities

Place models and worldwide place data for Django

PyPI version Build status


django-cities provides you with place related models (eg. Country, Region, City) and data (from GeoNames) that can be used in your django projects.

This package officially supports all currently supported versions of Python/Django:

Python 3.6 3.7 3.8 3.9 3.10
Django 2.2
Django 3.1
Django 3.2
Django 4.0
Key
Officially supported, tested, and passing
🔵 Tested and passing, but not officially supported
Known incompatibilities

Authored by Ben Dowling, and some great contributors.

See some of the data in action at city.io and country.io.



Requirements

Your database must support spatial queries, see the GeoDjango documentation for details and setup instructions.

Installation

Clone this repository into your project:

git clone https://github.com/coderholic/django-cities.git

Download the zip file and unpack it:

wget https://github.com/coderholic/django-cities/archive/master.zip
unzip master.zip

Install with pip:

pip install django-cities

Configuration

You'll need to enable GeoDjango. See that documentation for guidance.

You'll need to add cities to INSTALLED_APPS in your projects settings.py file:

INSTALLED_APPS = (
    # ...
    'cities',
    # ...
)

Migration Configuration

These settings should be reviewed and set or modified BEFORE any migrations have been run.

Swappable Models

Some 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.

To 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:

Here's an example my_cities_app/models.py:

from django.db import models

from cities.models import BaseCountry


class CustomCountryModel(BaseCountry, models.Model):
    more_data = models.TextField()

    class Meta(BaseCountry.Meta):
        pass

Then you will need to configure your project by setting the appropriate option:

Model Setting Name Default Value
Continent CITIES_CONTINENT_MODEL cities.Continent
Country CITIES_COUNTRY_MODEL cities.Country
City CITIES_CITY_MODEL cities.City

So to use the CustomCountryModel we defined above, we would add the dotted model string to our project's settings.py:

# ...

CITIES_COUNTRY_MODEL = 'my_cities_app.CustomCountryModel'

# ...

The dotted model string is simply the dotted import path with the .models substring removed, just <app_label>.<model_class_name>.

Once 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.

Alternative Name Types

The 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.

These settings should be specified as a tuple of tuple choices:

CITIES_AIRPORT_TYPES = (
    ('iata', _("IATA (Airport) Code")),
    ('icao', _("ICAO (Airport) Code")),
    ('faac', _("FAAC (Airport) Code")),
)

CITIES_ALTERNATIVE_NAME_TYPES = (
    ('name', _("Name")),
    ('abbr', _("Abbreviation")),
    ('link', _("Link")),
)

If 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.

The Geonames data also contains alternative names that are purely numeric.

The 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.

Continent Data

Since 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.

For an overview of different continent models, please see the Wikipedia article on Continents:

https://en.wikipedia.org/wiki/Continent#Number

The following is the default continent data in cities/conf.py:

CITIES_CONTINENT_DATA = {
    'AF': ('Africa', 6255146),
    'AS': ('Asia', 6255147),
    'EU': ('Europe', 6255148),
    'NA': ('North America', 6255149),
    'OC': ('Oceania', 6255151),
    'SA': ('South America', 6255150),
    'AN': ('Antarctica', 6255152),
}

Note 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.

Run Migrations

After you have configured all migration settings, run

python manage.py migrate cities

to create the required database tables and add the continent data to its table.

Import Configuration

These 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.

Download Directory

Specify a download directory (used to specify a writable directory).

Default: cities/data

You may want to use this if you are on a cloud services provider, or if django-cities is installed on a read-only medium.

Note that this path must be an absolute path.

CITIES_DATA_DIR = '/var/data'

Download Files

You can override the files the import command uses to process data:

CITIES_FILES = {
    # ...
    'city': {
       'filename': 'cities1000.zip',
       'urls':     ['http://download.geonames.org/export/dump/'+'{filename}']
    },
    # ...
}

It 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.

CITIES_FILES = {
    # ...
    'city': {
       'filenames': ["US.zip", "GB.zip", ],
       'urls':      ['http://download.geonames.org/export/dump/'+'{filename}']
    },
    # ...
}

Note 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.

Currency Data

The 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.

However, 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.

For default values see the included cities/conf.py file.

CITIES_CURRENCY_SYMBOLS = {
    "AED": "د.إ", "AFN": "؋", "ALL": "L", "AMD": "դր.", "ANG": "ƒ", "AOA": "Kz",
    "ARS": "$", "AUD": "$", "AWG": "ƒ", "AZN": "m",
    "BAM": "KM", "BBD": "$", "BDT": "৳", "BGN": "лв", "BHD": "ب.د", "BIF": "Fr",
    # ...
    "UAH": "₴", "UGX": "Sh", "USD": "$", "UYU": "$", "UZS": "лв",

Countries That No Longer Exist

The 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 ([]).

Default: ['CS', 'AN']

CITIES_NO_LONGER_EXISTENT_COUNTRY_CODES = ['CS', 'AN']

Postal Code Validation

The 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.

If 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).

CITIES_VALIDATE_POSTAL_CODES = True

Custom slugify() Function

You 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:

CITIES_SLUGIFY_FUNCTION = 'cities.util.default_slugify'

Your 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.

Because 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__).

Default slugify function (see cities/util.py):

# SLUGIFY REGEXES

to_und_rgx = re.compile(r"[']", re.UNICODE)
slugify_rgx = re.compile(r'[^-\w._~]', re.UNICODE)
multi_dash_rgx = re.compile(r'-{2,}', re.UNICODE)
dash_und_rgx = re.compile(r'[-_]_', re.UNICODE)
und_dash_rgx = re.compile(r'[-_]-', re.UNICODE)
starting_chars_rgx = re.compile(r'^[-._]*', re.UNICODE)
ending_chars_rgx = re.compile(r'[-._]*$', re.UNICODE)


def default_slugify(obj, value):
    if value is None:
        return None

    value = force_text(unicode_func(value))
    value = unicodedata.normalize('NFKC', value.strip())
    value = re.sub(to_und_rgx, '_', value)
    value = re.sub(slugify_rgx, '-', value)
    value = re.sub(multi_dash_rgx, '-', value)
    value = re.sub(dash_und_rgx, '_', value)
    value = re.sub(und_dash_rgx, '_', value)
    value = re.sub(starting_chars_rgx, '', value)
    value = re.sub(ending_chars_rgx, '', value)
    return mark_safe(value)

Cities Without Regions

Note: This used to be CITIES_IGNORE_EMPTY_REGIONS.

Some 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:

# Import cities without region (default False)
CITIES_SKIP_CITIES_WITH_EMPTY_REGIONS = True

Languages/Locales To Import

Limit imported alternative names by languages/locales

Note 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.

Special values:

  • ALL - import all alternative names
  • 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.
  • LANGUAGES - a "shortcut" to import all alternative names specified in the LANGUAGES setting in your Django project's settings.py

For a full list of ISO639-1 language codes, see the iso-languagecodes.txt file on Geonames.

CITIES_LOCALES = ['en', 'und', 'LANGUAGES']

Limit Imported Postal Codes

Limit the imported postal codes to specific countries

Special value:

  • ALL - import all postal codes
CITIES_POSTAL_CODES = ['US', 'CA']

Plugins

You can write your own plugins to process data before and after it is written to the database. See the section on Writing Plugins for details.

To 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:

CITIES_PLUGINS = [
    # Canadian postal codes need region codes remapped to match geonames
    'cities.plugin.postal_code_ca.Plugin',
    # Reduce memory usage when importing large datasets (e.g. "allCountries.zip")
    'cities.plugin.reset_queries.Plugin',
]

Note that some plugins may use their own configuration options:

# This setting may be specified if you use 'cities.plugin.reset_queries.Plugin'
CITIES_PLUGINS_RESET_QUERIES_CHANCE = 1.0 / 1000000

Import Data

After you have configured all import settings, run

python manage.py cities --import=all

to import all of the place data.

You may also import specific object types:

python manage.py cities --import=country
python manage.py cities --import=city

NOTE: This can take a long time, although there are progress bars drawn in the terminal.

Specifically, importing postal codes can take one or two orders of magnitude more time than importing other objects.

Writing Plugins

You 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.

A 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.

Here's a table of all available hooks:

Model Pre Hook Name Post Hook Name
Country country_pre country_post
Region region_pre region_post
Subregion subregion_pre subregion_post
City city_pre city_post
District district_pre district_post
PostalCode postal_code_pre postal_code_post
AlternativeName alt_name_pre alt_name_post

The argument signatures for _pre hooks and _post hooks differ. All _pre hooks have the following argument signature:

class ...Plugin(object):
    model_pre(self, parser, item)

whereas all _post hooks also have the saved model instance available to them:

class ...Plugin(object):
    model_post(self, parser, <model>_instance, item)

Arguments passed to hooks:

  • self - the plugin object itself
  • parser - the instance of the cities.Command management command
  • <model>_instance - instance of model that was created based on item
  • item - Python dictionary with data for row being processed

Note that the argument names are simply conventions, you are free to rename them to whatever you wish as long as you keep their order.

Here is a complete skeleton plugin class example:

class CompleteSkeletonPlugin(object):
    """
    Skeleton plugin for django-cities that has hooks for all object types, and
    does not modify any import data or existing objects in the database.
    """
    # Note: Only ONE of these methods needs to be defined. If a method is not
    #       defined, the import command will avoid calling the undefined method.

    def country_pre(self, parser, imported_data_dict):
        pass

    def country_post(self, parser, country_instance, imported_data_dict):
        pass

    def region_pre(self, parser, imported_data_dict):
        pass

    def region_post(self, parser, region_instance, imported_data_dict):
        pass

    def subregion_pre(self, parser, imported_data_dict):
        pass

    def subregion_post(self, parser, subregion_instance, imported_data_dict):
        pass

    def city_pre(self, parser, imported_data_dict):
        pass

    def city_post(self, parser, city_instance, imported_data_dict):
        pass

    def district_pre(self, parser, imported_data_dict):
        pass

    def district_post(self, parser, district_instance, imported_data_dict):
        pass

    def alt_name_pre(self, parser, imported_data_dict):
        pass

    def alt_name_post(self, parser, alt_name_instance, imported_data_dict):
        pass

    def postal_code_pre(self, parser, imported_data_dict):
        pass

    def postal_code_post(self, parser, postal_code_instance, imported_data_dict):
        pass

Silly example:

from cities.conf import HookException

class DorothyPlugin(object):
    """
    This plugin skips importing cities that are not in Kansas, USA.
    
    There's no place like home.
    """
    def city_pre(self, parser, import_dict):
        if import_dict['cc2'] == 'US' and import_dict['admin1Code'] != 'KS':
            raise HookException("Ignoring cities not in Kansas, USA")  # Raising a HookException skips importing the item
        else:
            # Modify the value of the data before it is written to the database
            import_dict['admin1Code'] = 'KS'

    def city_post(self, parser, city, import_data):
        # Checks if the region foreign key for the city database row is NULL
        if city.region is None:
            # Set it to Kansas
            city.region = Region.objects.get(country__code='US', code='KS')
            # Re-save any existing items that aren't in Kansas
            city.save()

Once 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 section for details.

Examples

This repository contains an example project which lets you browse the place hierarchy. See the example directory. Below are some small snippets to show you the kind of queries that are possible once you have imported data:

# Find the 5 most populated countries in the World
>>> Country.objects.order_by('-population')[:5]
[<Country: China>, <Country: India>, <Country: United States>,
 <Country: Indonesia>, <Country: Brazil>]

# Find what country the .ly TLD belongs to
>>> Country.objects.get(tld='ly')
<Country: Libya>

# 5 Nearest cities to London
>>> london = City.objects.filter(country__name='United Kingdom').get(name='London')
>>> nearest = City.objects.distance(london.location).exclude(id=london.id).order_by('distance')[:5]

# All cities in a state or county
>>> City.objects.filter(country__code="US", region__code="TX")
>>> City.objects.filter(country__name="United States", subregion__name="Orange County")

# Get all countries in Japanese preferring official names if available,
# fallback on ASCII names:
>>> [country.alt_names_ja.get_preferred(default=country.name) for country in Country.objects.all()]

# Alternate names for the US in English, Spanish and German
>>> [x.name for x in Country.objects.get(code='US').alt_names.filter(language_code='de')]
[u'USA', u'Vereinigte Staaten']
>>> [x.name for x in Country.objects.get(code='US').alt_names.filter(language_code='es')]
[u'Estados Unidos']
>>> [x.name for x in Country.objects.get(code='US').alt_names.filter(language_code='en')]
[u'United States of America', u'America', u'United States']

# Alternative names for Vancouver, Canada
>>> City.objects.get(name='Vancouver', country__code='CA').alt_names.all()
[<AlternativeName: 溫哥華 (yue)>, <AlternativeName: Vankuver (uz)>,
 <AlternativeName: Ванкувер (ce)>, <AlternativeName: 溫哥華 (zh)>,
 <AlternativeName: वैंकूवर (hi)>, <AlternativeName: Ванкувер (tt)>,
 <AlternativeName: Vankuveris (lt)>, <AlternativeName: Fankoever (fy)>,
 <AlternativeName: فانكوفر (arz)>, <AlternativeName: Ванкувер (mn)>,
 <AlternativeName: ဗန်ကူးဗားမ_ (my)>, <AlternativeName: व्हँकूव्हर (mr)>,
 <AlternternativeName: வான்கூவர் (ta)>, <AlternativeName: فانكوفر (ar)>,
 <AlternativeName: Vankuver (az)>, <AlternativeName: Горад Ванкувер (be)>,
 <AlternativeName: ভ্যানকুভার (bn)>, <AlternativeName: แวนคูเวอร์ (th)>,
 <Al <AlternativeName: Ванкувер (uk)>, <AlternativeName: ਵੈਨਕੂਵਰ (pa)>,
 '...(remaining elements truncated)...']

# Get zip codes near Mountain View, CA
>>> PostalCode.objects.distance(City.objects.get(name='Mountain View', region__name='California').location).order_by('distance')[:5]
[<PostalCode: 94040>, <PostalCode: 94041>, <PostalCode: 94043>,
 <PostalCode: 94024>, <PostalCode: 94022>]

Third-party Apps / Extensions

These are apps that build on top of the django-cities. Useful for essentially extending what django-cities can do.

  • django-airports provides you with airport related model and data (from OpenFlights) that can be used in your Django projects.

TODO

In increasing order of difficulty:

  • Add tests for the plugins we ship with
  • Minimize number of attributes on abstract base models and adjust import script accordingly
  • Steal/modify all of the contrib apps from django-contrib-light (Django REST Framework integration, chained selects, and autocomplete)
  • Integrate libpostal to extract Country/City/District/Postal Code from an address string

Notes

Some datasets are very large (> 100 MB) and take time to download/import.

Data will only be downloaded/imported if it is newer than your data, and only matching rows will be overwritten.

The cities manage command has options, see --help. Verbosity is controlled through the LOGGING setting.

Running Tests

  1. Install postgres, postgis and libgdal-dev

  2. Create django_cities database:

     sudo su -l postgres
     # Enter your password
     createuser -d -s -P some_username
     # Enter password
     createdb -T template0 -E utf-8 -l en_US.UTF-8 -O multitest django_cities
     psql  -c 'create extension postgis;' -d django_cities
    
  3. Run tests:

     POSTGRES_USER=some_username POSTGRES_PASSWORD='password from createuser step' tox
    
     # If you have changed example data files then you should push your
     # changes to github and specify commit and repo variables:
     TRAVIS_COMMIT=`git rev-parse HEAD` TRAVIS_REPO_SLUG='github-username/django-cities' POSTGRES_USER=some_username POSTGRES_PASSWORD='password from createuser ste' tox
    

As an alternative to installing and running PostgreSQL system-wide, you can run the tests against a transient Docker instance:

docker run --rm -p 127.0.0.1:5432:5432 mdillon/postgis

Useful test options:

  • TRAVIS_LOG_LEVEL - defaults to INFO, but set to DEBUG to see a (very) large and (very) complete log of the import script
  • CITIES_FILES - set the base urls to a file:// path to use local files without modifying any other settings

Release Notes

0.4.1

Use Django's native migrations

Upgrading from 0.4.1

Upgrading 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:

python manage.py migrate cities 0001 --fake

0.4

** This release of django-cities is not backwards compatible with previous versions **

The country model has some new fields:

  • elevation
  • area
  • currency
  • currency_name
  • languages
  • neighbours
  • capital
  • phone

Alternative name support has been completely overhauled. The code and usage should now be much simpler. See the updated examples below.

The 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".

These 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.

django-cities's People

Contributors

adamhaney avatar angvp avatar arthanson avatar bashu avatar blag avatar coderholic avatar erickgnavar avatar eugena avatar flebel avatar georgema1982 avatar gugu avatar imposeren avatar jscott1971 avatar leogregianin avatar lockie avatar mbaragiola avatar mbegoc avatar mehdipourfar avatar mikluko avatar mxschmitt avatar njamaleddine avatar pidelport avatar qarterd avatar rafapinzon93 avatar riz avatar scotteadams avatar shanto avatar spout avatar timrchavez avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-cities's Issues

Importing Postal Code Data

Hi, Thanks again for the great package. However, I havent been able to import PostalCode data from the commands:

./manage.py cities --import=postal_code

Also, running ./manage.py cities --import=all imports data for every field except PostalCode. What is the problem with this? How can I get the data for postal codes into my database?

No PostalCode Field in Pypi version

Hi, Thanks for creating a great django module. After installing via pip, I noticed that there is no PostalCode model in the pypi version, while there is in the git version. Both versions say they are 0.2, which led to some confusion for me. I ended up using the git version and it works great. Thanks!

./manage.py cities --import=all stops due to AttributeError

Hi,

I have installed django-cities in one of my geo-spatial projects (postgis works fine). The installation of django-cities was effortless and the dbsync worked fine as well.

However, when I try to execute "./manage.py cities --import=all", the import function throws the following error message after 20 seconds. Can you please give me an understanding what might cause this error? Thank you!

./manage.py cities --import=all
Traceback (most recent call last):
File "./manage.py", line 23, in
execute_from_command_line()
File "/Users/h/Development/v/lib/python2.7/site-packages/django/core/management/init.py", line 429, in execute_from_command_line
utility.execute()
File "/Users/h/Development/v/lib/python2.7/site-packages/django/core/management/init.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/h/Development/v/lib/python2.7/site-packages/django/core/management/base.py", line 191, in run_from_argv
self.execute(_args, *_options.dict)
File "/Users/h/Development/v/lib/python2.7/site-packages/django/core/management/base.py", line 220, in execute
output = self.handle(_args, *_options)
File "/Users/h/Development/v/lib/python2.7/site-packages/cities/management/commands/cities.py", line 70, in handle
func()
File "/Users/h/Development/v/lib/python2.7/site-packages/cities/management/commands/cities.py", line 233, in import_subregion
if not self.call_hook('subregion_pre', items): continue
File "/Users/h/Development/v/lib/python2.7/site-packages/cities/management/commands/cities.py", line 73, in call_hook
for plugin in settings.plugins[hook]:
AttributeError: type object '' has no attribute 'plugins'

Remove magic in import scripts

I've been reading through the import scripts and have found multiple places where the import scripts were set to silently fail when the data was not in the exact correct format. among other problems:

  1. There NEEDS to be a transaction around the import process. At the very least have @method_decorator(transaction.commit_on_success) on the handle() method. This one line cuts my import time in half and ensures my db is never incomplete.

  2. tab delimited files are not opened with csv.Reader, cannot take advantage of header names, entire file is read into memory instead of iterated over. I'd imagine this to introduce a reasonable performance penalty....

  3. There is also a LOT of magic numbers everywhere:

    country.name = items[4]
    country.code = items[0]
    country.population = items[7]
    country.continent = items[8]
    country.tld = items[9][1:]
    

    needs something more like this:

    country.name = row[HEADER_COUNTRY_NAME]
    
  4. There needs to be some effort put in to explicitly define what happens when data does not line up:

    try: country.id = int(items[16])
    except: continue
    

    This fails any country that does not have a column 16. What is column 16? why would it be missing? what does this mean for the rest of the imported data?

I'm happy to work on this code if someone is happy to go through what all the table columns are with me, because I don't have a clue....

import does not work

I have run

./manage.py cities --import=all

it does not write a single line.

I have following settings:

CITIES_LOCALES = ['en', 'cs', 'LANGUAGES']

# Postal codes will be imported for all ISO 3166-1 alpha-2 country codes below.
# See cities.conf for a full list of country codes.
# See download.geonames.org/export/dump/countryInfo.txt
CITIES_POSTAL_CODES = ['US', 'CA', 'CS']

# List of plugins to process data during import
CITIES_PLUGINS = [
]

Import seems to be fine but when I try to look for anything it does nothing:

>>> from cities.models import Country, Region, City, District
>>> City.objects.filter()
[]
>>> 

What should I do?

Some cities / region are duplicated

Hi :)

We are using your Library and we face a multipleobject with some of the cities.

=> select slug, count(*) from cities_region group by slug, country_id having count(*) > 1;
    slug      | count 
---------------+-------
daugavpils    |    2
lima          |    2
ash-sharqiyah |    2
vientiane    |    2
al-batinah    |    2
(5 rows)

What do you think it could be ?

Hierarchy is no longer fixed

When I merged in one of Kometes pull requests I missed that it breaks the fixed hierarchy. It's now possible to have either one or two regions per city. That makes it much harder to work out the target model, eg:

/united-kingdom/england/hemsworth -> City
/united-kingdom/england/borough-of-swindon -> Region

It also adds a lot of complexity when creating place directories, because you need to check the region hierarchy. The hierarchy was originally fixed by design, and I'd like to return it to a fixed hierarchy. It'd be great to get some input on the best way to return to one while causing minimum disruption and still supporting all required use cases. I'm currently thinking of a new SubRegion class, and having a ForeignKey to both region and subregion on City. That way you could completely ignore SubRegions should you choose to.

lot of "cannot find region"

Is it normal to have this behavior while importing datas ?

(lot of)
City: Henstedt-Ulzburg: Cannot find region 2: DE.10.00
City: Wesenberg: Cannot find region 2: DE.10.00
City: Moraas: Cannot find region 2: DE.12.00
City: Fargau-Pratjau: Cannot find region 2: DE.10.00
City: Admannshagen-Bargeshagen: Cannot find region 2: DE.12.00
City: Bartenshagen-Parkentin: Cannot find region 2: DE.12.00
City: Borgerende-Rethwisch: Cannot find region 2: DE.12.00
City: Diensdorf-Radlow: Cannot find region 2: DE.11.00
City: Bruchhausen: Cannot find region 2: DE.08.00
City: Brohl-Lutzing: Cannot find region 2: DE.08.00
City: Schmedeswurth: Cannot find region 2: DE.10.00
City: Barnitz: Cannot find region 2: DE.10.00
City: Peterswald-Loffelscheid: Cannot find region 2: DE.08.00
City: Stadecken-Elsheim: Cannot find region 2: DE.08.00
City: Dannstadt-Schauernheim: Cannot find region 2: DE.08.00
City: Rodersheim-Gronau: Cannot find region 2: DE.08.00
City: Billigheim-Ingenheim: Cannot find region 2: DE.08.00
City: Bohl-Iggelheim: Cannot find region 2: DE.08.00
City: Hochdorf-Assenheim: Cannot find region 2: DE.08.00
City: Dittelsheim-Hessloch: Cannot find region 2: DE.08.00
City: Hochborn: Cannot find region 2: DE.08.00
City: Heuchelheim-Klingen: Cannot find region 2: DE.08.00
and so on

Spatialite: DatabaseError: no such table: spatial_ref_sys

The import seems to run for a long while but after about an hour and half it craps out as per the below error, any suggestions before I start tearing into the issue? Me thinks it might be Spatialite setup, Super thank you!

#python manage.py cities --import=all --settings=settings_development
...
DEBUG cities cities.py@304: Added city: Banket, Mashonaland West Province, Zimbabwe
DEBUG django.db.backends util.py@51: (0.000) SELECT (1) AS "a" FROM "cities_city" WHERE "cities_city"."id" = 1106542  LIMIT 1; args=(1106542,)
DEBUG django.db.backends util.py@51: (0.001) INSERT INTO "cities_city" ("id", "name", "slug", "name_std", "location", "population", "region_id", "subregion_id", "country_id") VALUES (1106542, Chitungwiza, chitungwiza, Chitungwiza, GeomFromText(POINT (31.0755499999999998 -18.0127400000000009),4326), 340360, 1105844, None, 878675); args=[1106542, 'Chitungwiza', u'chitungwiza', 'Chitungwiza', <django.contrib.gis.db.backends.spatialite.adapter.SpatiaLiteAdapter object at 0x19112e4c>, 340360, 1105844, None, 878675]
DEBUG cities cities.py@304: Added city: Chitungwiza, Harare Province, Zimbabwe
INFO cities cities.py@112: Downloading: hierarchy.zip
INFO cities cities.py@312: Building hierarchy index
INFO cities cities.py@328: Building city index
DEBUG django.db.backends util.py@51: (0.074) SELECT "cities_city"."id", "cities_city"."name", "cities_city"."slug", "cities_city"."name_std", AsText("cities_city"."location"), "cities_city"."population", "cities_city"."region_id", "cities_city"."subregion_id", "cities_city"."country_id" FROM "cities_city"; args=()
INFO cities cities.py@333: Importing district data
WARNING cities cities.py@347: District: Fier-Cifci: Cannot find city in hierarchy, using nearest
DEBUG django.db.backends util.py@51: (0.001) SELECT "spatial_ref_sys"."srid", "spatial_ref_sys"."auth_name", "spatial_ref_sys"."auth_srid", "spatial_ref_sys"."ref_sys_name", "spatial_ref_sys"."proj4text" FROM "spatial_ref_sys" WHERE "spatial_ref_sys"."srid" = 4326 ; args=(4326,)
DatabaseError: no such table: spatial_ref_sys

Abbreviations of locations?

Hi,

Could it be that Django-Cities does not allow for abbreviations of locations? e.g. "Northrhein-Westphalen" (a German state) is commonly abbreviated as "NRW". The abbreviation can be found in Geonames for that state but we can't get it out on our end.

Data contains null bytes which is not supported by PostgreSQL

Loading data does not work with the new django-cities version on PostgreSQL 9.1.1 with PostGIS 1.5.3

time ./manage.py loaddata geonames_dump
Problem installing fixture '/srv/art/art_env/src/cities/cities/fixtures/geonames_dump.json': Traceback (most recent call last):
File "/srv/art/art_env/lib/python2.7/site-packages/django/core/management/commands/loaddata.py", line 174, in handle
obj.save(using=using)
File "/srv/art/art_env/lib/python2.7/site-packages/django/core/serializers/base.py", line 165, in save
models.Model.save_base(self.object, using=using, raw=True)
File "/srv/art/art_env/lib/python2.7/site-packages/django/db/models/base.py", line 553, in save_base
result = manager._insert(values, return_id=update_pk, using=using)
File "/srv/art/art_env/lib/python2.7/site-packages/django/db/models/manager.py", line 195, in _insert
return insert_query(self.model, values, **kwargs)
File "/srv/art/art_env/lib/python2.7/site-packages/django/db/models/query.py", line 1436, in insert_query
return query.get_compiler(using=using).execute_sql(return_id)
File "/srv/art/art_env/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 791, in execute_sql
cursor = super(SQLInsertCompiler, self).execute_sql(None)
File "/srv/art/art_env/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 735, in execute_sql
cursor.execute(sql, params)
File "/srv/art/art_env/lib/python2.7/site-packages/django/db/backends/util.py", line 34, in execute
return self.cursor.execute(sql, params)
File "/srv/art/art_env/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 44, in execute
return self.cursor.execute(query, args)
DatabaseError: invalid byte sequence for encoding "UTF8": 0x00

./manage.py loaddata geonames_dump 13.49s user 0.59s system 85% cpu 16.390 total

Please let me know if I can provide any other information.

Django 1.6 changed the default value of BooleanField from False to None

I am getting the following:

cities.CityAltNameEn.is_preferred: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more
information.
cities.CityAltNameEn.is_short: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more
information.
cities.CityAltNameUnd.is_preferred: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more
information.
cities.CityAltNameUnd.is_short: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more
information.
cities.CountryAltNameEn.is_preferred: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more
information.
cities.CountryAltNameEn.is_short: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.

    HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.

cities.CountryAltNameUnd.is_preferred: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.
cities.CountryAltNameUnd.is_short: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.
cities.DistrictAltNameEn.is_preferred: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.
cities.DistrictAltNameEn.is_short: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.
cities.DistrictAltNameUnd.is_preferred: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.
cities.DistrictAltNameUnd.is_short: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.
cities.RegionAltNameEn.is_preferred: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.
cities.RegionAltNameEn.is_short: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.
cities.RegionAltNameUnd.is_preferred: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.
cities.RegionAltNameUnd.is_short: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.
cities.SubregionAltNameEn.is_preferred: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.
cities.SubregionAltNameEn.is_short: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.
cities.SubregionAltNameUnd.is_preferred: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.
cities.SubregionAltNameUnd.is_short: (1_6.W002) BooleanField does not have a default value.
HINT: Django 1.6 changed the default value of BooleanField from False to None. See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield for more information.

Failed to Install Index

Hi There,

First of all, thanks for sharing the app! I got the following output after running syncdb (I am using a PostgreSQL db with PostGIS 2.0 and Django 1.4.1):

Syncing...
Creating tables ...
Creating table cities_country
Creating table cities_region
Creating table cities_subregion
Creating table cities_city
Creating table cities_district
Creating table cities_country_alt_name_en
Creating table cities_country_alt_name_und
Creating table cities_region_alt_name_en
Creating table cities_region_alt_name_und
Creating table cities_subregion_alt_name_en
Creating table cities_subregion_alt_name_und
Creating table cities_city_alt_name_en
Creating table cities_city_alt_name_und
Creating table cities_district_alt_name_en
Creating table cities_district_alt_name_und
Installing custom SQL ...
Installing indexes ...
Failed to install index for cities.City model: AddGeometryColumn() - invalid SRID
CONTEXT: SQL statement "SELECT AddGeometryColumn('','',$1,$2,$3,$4,$5, $6)"
PL/pgSQL function "addgeometrycolumn" line 5 at SQL statement

Failed to install index for cities.District model: AddGeometryColumn() - invalid SRID
CONTEXT: SQL statement "SELECT AddGeometryColumn('','',$1,$2,$3,$4,$5, $6)"
PL/pgSQL function "addgeometrycolumn" line 5 at SQL statement

Any help would be great, thanks!!

Fei

Latitude and Longitude Switched in Import Script

Hi Ben,
Thanks for this project -- the import script especially is very useful!

I think I've spotted one small bug: the import script seems to be switching latitude and longitude for both City and District locations.

Lines 86 and 145 of import.py construct City and District Point objects as: Point(float(items[4]), float(items[5]), where I think it should be Point(float(items[5]), float(items[4]). In GeoNames cities1000.txt, col 5 (Items[4]) is Latitude and col 6 (items[5]) is Longitude. The Point constructor takes the arguments Point(x, y) or Point(Lon, Lat) instead of point Point(Lat, Lon) (see http://groups.google.com/group/django-users/browse_thread/thread/80dae95ee8f76361?pli=1).

Thanks again and keep up the good work!

Kevin

Remove postalcode & altname "magic"

Currently the optional postcode and alternative name models are dynamically generated based on configuration details provided in settings.py, and a separate model is created for each of the different configuration options. I think the code would be much more readable and maintainable if this magic is removed.

@kometes sorry for not flagging this at the time you issued your pull request - I should have been paying closer attention but was super busy at the time. It'd be great it you could give me some insight into why you took this approach, and why you feel it works better than having single PostalCode and AltName models that have a country and locale field respectively, instead of a model for every country and locale?

Admin.py

Somehow (some django magic involved) moving the admin registration call into an admin.py file resolved some weird import dependencies we could not resolved in our project.

We're forking it an will send a pull request. No change to code, just moved 5-6 lines to another file, the way it should be done.

Using the Places model

I want to be able to use the Place model in its own right - ie one model that combines all the rest. But, with abstract=True it doesn't let me.

I get programming error when taking out abstract=True (and the Place model doesn't have a table associated with it and migrating doesn't create them).

Is there any way to use the Place model within an already set up django-cities app?

Cheers!

AttributeError: 'DatabaseOperations' object has no attribute 'geo_db_type' with Django 1.7

I'm trying to use django-cities with the new version of Django (1.7) and when I try to run the python manage.py syncdb command to create django-cities tables I got the following error (full traceback):

Operations to perform:
  Synchronize unmigrated apps: cities
  Apply all migrations: admin, contenttypes, auth, sessions
Synchronizing apps without migrations:
  Creating tables...
    Creating table cities_country_neighbours
    Creating table cities_country_alt_names
    Creating table cities_country
    Creating table cities_region_alt_names
    Creating table cities_region
    Creating table cities_subregion_alt_names
    Creating table cities_subregion
    Creating table cities_city_alt_names
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/Users/cristianrojas/.virtualenvs/bbintlcargo/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
    utility.execute()
  File "/Users/cristianrojas/.virtualenvs/bbintlcargo/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/cristianrojas/.virtualenvs/bbintlcargo/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/Users/cristianrojas/.virtualenvs/bbintlcargo/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
    output = self.handle(*args, **options)
  File "/Users/cristianrojas/.virtualenvs/bbintlcargo/lib/python2.7/site-packages/django/core/management/base.py", line 533, in handle
    return self.handle_noargs(**options)
  File "/Users/cristianrojas/.virtualenvs/bbintlcargo/lib/python2.7/site-packages/django/core/management/commands/syncdb.py", line 27, in handle_noargs
    call_command("migrate", **options)
  File "/Users/cristianrojas/.virtualenvs/bbintlcargo/lib/python2.7/site-packages/django/core/management/__init__.py", line 115, in call_command
    return klass.execute(*args, **defaults)
  File "/Users/cristianrojas/.virtualenvs/bbintlcargo/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
    output = self.handle(*args, **options)
  File "/Users/cristianrojas/.virtualenvs/bbintlcargo/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 128, in handle
    created_models = self.sync_apps(connection, executor.loader.unmigrated_apps)
  File "/Users/cristianrojas/.virtualenvs/bbintlcargo/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 228, in sync_apps
    sql, references = connection.creation.sql_create_model(model, no_style(), seen_models)
  File "/Users/cristianrojas/.virtualenvs/bbintlcargo/lib/python2.7/site-packages/django/db/backends/creation.py", line 82, in sql_create_model
    col_type = f.db_type(connection=self.connection)
  File "/Users/cristianrojas/.virtualenvs/bbintlcargo/lib/python2.7/site-packages/django/contrib/gis/db/models/fields.py", line 220, in db_type
    return connection.ops.geo_db_type(self)
AttributeError: 'DatabaseOperations' object has no attribute 'geo_db_type'

error: column cities_city.subregion_id does not exist

Is this a bug, or do we have a migration / South problem?

When we add places without cities, we get the error column cities_city.subregion_id does not exist.

I have fixed it with ALTER TABLE cities_city ADD COLUMN subregion_id integer; but wonder if there's a by the book way of doing it?

./manage.py cities fails on postgis

Postgresql: 9.1.1
Postgis: 1.5
Geos: 3.3.0-1
Proj: 4.7.0
Django: 1.3,1
Distro: Arch

Settings:

CITIES_FILES = {
    'city': {
       'filename': 'cities5000.zip',
       'urls':     ['http://download.geonames.org/export/dump/'+'{filename}']
    },
}

CITIES_POSTAL_CODES = ['US','CA', 'FR']
CITIES_LOCALES = ['en', 'fr']
CITIES_PLUGINS = [
    'cities.plugin.postal_code_ca.Plugin',
]

Error when running "cities" command:

Traceback (most recent call last):
  File "./manage.py", line 20, in <module>
    execute_from_command_line()
  File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/core/management/__init__.py", line 429, in execute_from_command_line
    utility.execute()
  File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/core/management/__init__.py", line 379, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/core/management/base.py", line 191, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/core/management/base.py", line 220, in execute
    output = self.handle(*args, **options)
  File "/srv/art_dev/art_dev_env/src/cities/cities/management/commands/cities.py", line 68, in handle
    func()
  File "/srv/art_dev/art_dev_env/src/cities/cities/management/commands/cities.py", line 494, in import_postal_code
    pc.save()
  File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/db/models/base.py", line 460, in save
    self.save_base(using=using, force_insert=force_insert, force_update=force_update)
  File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/db/models/base.py", line 553, in save_base
    result = manager._insert(values, return_id=update_pk, using=using)
  File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/db/models/manager.py", line 195, in _insert
    return insert_query(self.model, values, **kwargs)
  File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/db/models/query.py", line 1436, in insert_query
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 791, in execute_sql
    cursor = super(SQLInsertCompiler, self).execute_sql(None)
  File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 735, in execute_sql
    cursor.execute(sql, params)
  File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/db/backends/util.py", line 34, in execute
    return self.cursor.execute(sql, params)
  File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 44, in execute
    return self.cursor.execute(query, args)
django.db.utils.DatabaseError: invalid byte sequence for encoding "UTF8": 0x00

Also here are some errors from shell_plus command:

Failed to import 'CountryAltNameFr' from 'cities' reason: 'module' object has no attribute 'CountryAltNameFr'
Failed to import 'CountryAltNameEn' from 'cities' reason: 'module' object has no attribute 'CountryAltNameEn'
Failed to import 'RegionAltNameFr' from 'cities' reason: 'module' object has no attribute 'RegionAltNameFr'
Failed to import 'RegionAltNameEn' from 'cities' reason: 'module' object has no attribute 'RegionAltNameEn'
Failed to import 'CityAltNameFr' from 'cities' reason: 'module' object has no attribute 'CityAltNameFr'
Failed to import 'CityAltNameEn' from 'cities' reason: 'module' object has no attribute 'CityAltNameEn'
Failed to import 'DistrictAltNameFr' from 'cities' reason: 'module' object has no attribute 'DistrictAltNameFr'
Failed to import 'DistrictAltNameEn' from 'cities' reason: 'module' object has no attribute 'DistrictAltNameEn'
Failed to import 'PostalCodeCA' from 'cities' reason: 'module' object has no attribute 'PostalCodeCA'
Failed to import 'PostalCodeFR' from 'cities' reason: 'module' object has no attribute 'PostalCodeFR'
Failed to import 'PostalCodeUS' from 'cities' reason: 'module' object has no attribute 'PostalCodeUS'

Make it possible to filter cities per country

Wouldn't it be useful to be able to specify the countries that you want to import the cities for ? Maybe it's not necessary to import all cities of all countries in all projects.

import gb postal codes fails

Hi

I have the following issue when importing GB postal codes

FYI, line is 472 because i use the fork posted by kometes which handle mysql distance workaround ; i don't know if there is any link between this issue and fork version

Thanks

Traceback (most recent call last):
File "./manage.py", line 14, in
execute_manager(settings)
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django/core/management/init.py", line 438, in execute_manager
utility.execute()
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django/core/management/init.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django/core/management/base.py", line 191, in run_from_argv
self.execute(_args, *_options.dict)
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django/core/management/base.py", line 220, in execute
output = self.handle(_args, *_options)
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django_cities-0.18-py2.7.egg/cities/management/commands/cities.py", line 68, in handle
func()
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django_cities-0.18-py2.7.egg/cities/management/commands/cities.py", line 472, in import_postal_code
pc.location = Point(float(items[10]), float(items[9]))
ValueError: could not convert string to float:

A lot of quebec cities are in the wrong regions in initial_data.json

There is a lot of quebec cities in wrong regions

For example :
Laval (id:6050610) appears to be located in Northwest Territories,
Lavaltrie (id:6050650) appears in Nunavut,

We noticed at least 50 errors like those.

The lat-long are ok (but for Lasalle, there is indeed a lasalle located at those lat-long but the population is for another Lasalle(near of Montreal))

No mention of libgeos requirement.

At least in Django 1.2.3, this plugin will not run without installation of the libgeos C library. A mention of this in the documentation should be made.

CRITICAL/BLOCKING AttributeError: 'Settings' object has no attribute 'CITIES_FILES'

This is likely to have been caused by recent changes, when doing syncdb:

Traceback (most recent call last):
File "./manage.py", line 20, in
execute_from_command_line()
File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/core/management/init.py", line 429, in execute_from_command_line
utility.execute()
File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/core/management/init.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/core/management/base.py", line 191, in run_from_argv
self.execute(_args, *_options.dict)
File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/core/management/base.py", line 219, in execute
self.validate()
File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/core/management/base.py", line 249, in validate
num_errors = get_validation_errors(s, app)
File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/core/management/validation.py", line 35, in get_validation_errors
for (app_name, error) in get_app_errors().items():
File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/db/models/loading.py", line 146, in get_app_errors
self._populate()
File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/db/models/loading.py", line 61, in _populate
self.load_app(app_name, True)
File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/db/models/loading.py", line 78, in load_app
models = import_module('.models', app_name)
File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
import(name)
File "/srv/art_dev/art_dev_env/src/cities/cities/models.py", line 4, in
from conf import settings
File "/srv/art_dev/art_dev_env/src/cities/cities/conf.py", line 129, in
settings = create_settings()
File "/srv/art_dev/art_dev_env/src/cities/cities/conf.py", line 107, in create_settings
res.files.update(django_settings.CITIES_FILES)
File "/srv/art_dev/art_dev_env/lib/python2.7/site-packages/django/utils/functional.py", line 277, in getattr
return getattr(self._wrapped, name)
AttributeError: 'Settings' object has no attribute 'CITIES_FILES'

KeyError: 'fields'

Hi, I'm using Django1.5 and django-cities0.4 (zip downloaded from this repo) and I'm getting the following error when trying to make "python2.7 manage.py cities --force --import=all" on a fresh install:

KeyError: 'fields'

this is after a long time (around 20mins). After that, the following tables are populated (I'm not sure if all the data that should be loaded is loaded): cities_country, cities_country_neighbours, cities_region and cities_subregion. Also, the follogin tables are empty: cities_city, cities_district, cities_postalcode.

Multiple object exception for get_preferred

>>> from bp.cities.models import geo_alt_names, Region
>>> geo_alt_names[Region]["ru"].objects.get_preferred(geo__name="Adygeya", default="Adygeya")
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/home/lollo/src/html/bp/bp/bp/../bp/cities/models.py", line 109, in get_preferred
    try: return self.get(is_preferred=True, **kwargs)
  File "/usr/lib/python2.7/dist-packages/django/db/models/manager.py", line 143, in get
    return self.get_query_set().get(*args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/django/db/models/query.py", line 407, in get
    (self.model._meta.object_name, num))
MultipleObjectsReturned: get() returned more than one RegionAltNameRu -- it returned 2!

2013-12-19 00 37 55

NameError: global name 'geo_alt_names' is not defined

Hello,

On runing command :
./manage.py cities --flush=all

when is flushing alt_names error:

File "/home/aliona/hpn.aksprendimai.lt/aruodai/cities/management/commands/cities.py", line 517, in flush_alt_name
[geo_alt_name.objects.all().delete() for locales in geo_alt_names.values() for geo_alt_name in locales.values()]
NameError: global name 'geo_alt_names' is not defined

All another date flushing pass OK.

AttributeError: 'DatabaseOperations' object has no attribute 'mysql'

Error is the following


INFO Importing district data
WARNING District: Fier-Cifci: Cannot find city in hierarchy, using nearest

AttributeError: 'DatabaseOperations' object has no attribute 'mysql'

I am using Postgres for my backend.
'ENGINE': 'django.contrib.gis.db.backends.postgis'

All other tables [ie. city, regions, etc.. ] loaded properly into the database. Districts however fails to import with the above error. Stuck?

I am on ubuntu 12.x.x using bitnami djangostack 1.5.4 dev

django-cities crashes on syncdb with a fresh install of Django 1.6.2, GeoDjango, on Windows

Please be advised, I get the following traceback upon a syncdb of the "cities" app alongside the "geodjango" pre-requisite:

(funretire) C:\Users\code\workspace\funretire\src>python manage.py syncdb
Traceback (most recent call last):
File "manage.py", line 10, in
execute_from_command_line(sys.argv)
File "C:\Users\code\Envs\funretire\lib\site-packages\django\core\management__init__.py", line 399, in execute_from_command_line
utility.execute()
File "C:\Users\code\Envs\funretire\lib\site-packages\django\core\management__init__.py", line 392, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Users\code\Envs\funretire\lib\site-packages\django\core\management\base.py", line 242, in run_from_argv
self.execute(args, *options.dict)
File "C:\Users\code\Envs\funretire\lib\site-packages\django\core\management\base.py", line 284, in execute
self.validate()
File "C:\Users\code\Envs\funretire\lib\site-packages\django\core\management\base.py", line 310, in validate
num_errors = get_validation_errors(s, app)
File "C:\Users\code\Envs\funretire\lib\site-packages\django\core\management\validation.py", line 34, in get_validation_errors
for (app_name, error) in get_app_errors().items():
File "C:\Users\code\Envs\funretire\lib\site-packages\django\db\models\loading.py", line 196, in get_app_errors
self.populate()
File "C:\Users\code\Envs\funretire\lib\site-packages\django\db\models\loading.py", line 78, in populate
self.load_app(app_name)
File "C:\Users\code\Envs\funretire\lib\site-packages\django\db\models\loading.py", line 99, in load_app
models = import_module('%s.models' % app_name)
File "C:\Users\code\Envs\funretire\lib\site-packages\django\utils\importlib.py", line 40, in import_module
import(name)
File "C:\Users\code\Envs\funretire\lib\site-packages\cities\models.py", line 2, in
from django.contrib.gis.db import models
File "C:\Users\code\Envs\funretire\lib\site-packages\django\contrib\gis\db\models__init
.py", line 8, in
from django.contrib.gis.db.models.manager import GeoManager
File "C:\Users\code\Envs\funretire\lib\site-packages\django\contrib\gis\db\models\manager.py", line 2, in
from django.contrib.gis.db.models.query import GeoQuerySet
File "C:\Users\code\Envs\funretire\lib\site-packages\django\contrib\gis\db\models\query.py", line 6, in
from django.contrib.gis.db.models.fields import get_srid_info, PointField, LineStringField
File "C:\Users\code\Envs\funretire\lib\site-packages\django\contrib\gis\db\models\fields.py", line 4, in
from django.contrib.gis import forms
File "C:\Users\code\Envs\funretire\lib\site-packages\django\contrib\gis\forms__init
.py", line 2, in
from .fields import (GeometryField, GeometryCollectionField, PointField,
File "C:\Users\code\Envs\funretire\lib\site-packages\django\contrib\gis\forms\fields.py", line 11, in
from django.contrib.gis.geos import GEOSException, GEOSGeometry, fromstr
ImportError: cannot import name GEOSException

(funretire) C:\Users\code\workspace\funretire\src>python manage.py syncdb
Traceback (most recent call last):
File "manage.py", line 10, in
execute_from_command_line(sys.argv)
File "C:\Users\code\Envs\funretire\lib\site-packages\django\core\management__init__.py", line 399, in execute_from_command_line
utility.execute()
File "C:\Users\code\Envs\funretire\lib\site-packages\django\core\management__init__.py", line 392, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Users\code\Envs\funretire\lib\site-packages\django\core\management\base.py", line 242, in run_from_argv
self.execute(args, *options.dict)
File "C:\Users\code\Envs\funretire\lib\site-packages\django\core\management\base.py", line 284, in execute
self.validate()
File "C:\Users\code\Envs\funretire\lib\site-packages\django\core\management\base.py", line 310, in validate
num_errors = get_validation_errors(s, app)
File "C:\Users\code\Envs\funretire\lib\site-packages\django\core\management\validation.py", line 34, in get_validation_errors
for (app_name, error) in get_app_errors().items():
File "C:\Users\code\Envs\funretire\lib\site-packages\django\db\models\loading.py", line 196, in get_app_errors
self.populate()
File "C:\Users\code\Envs\funretire\lib\site-packages\django\db\models\loading.py", line 78, in populate
self.load_app(app_name)
File "C:\Users\code\Envs\funretire\lib\site-packages\django\db\models\loading.py", line 99, in load_app
models = import_module('%s.models' % app_name)
File "C:\Users\code\Envs\funretire\lib\site-packages\django\utils\importlib.py", line 40, in import_module
import(name)
File "C:\Users\code\Envs\funretire\lib\site-packages\cities\models.py", line 2, in
from django.contrib.gis.db import models
File "C:\Users\code\Envs\funretire\lib\site-packages\django\contrib\gis\db\models__init
.py", line 8, in
from django.contrib.gis.db.models.manager import GeoManager
File "C:\Users\code\Envs\funretire\lib\site-packages\django\contrib\gis\db\models\manager.py", line 2, in
from django.contrib.gis.db.models.query import GeoQuerySet
File "C:\Users\code\Envs\funretire\lib\site-packages\django\contrib\gis\db\models\query.py", line 6, in
from django.contrib.gis.db.models.fields import get_srid_info, PointField, LineStringField
File "C:\Users\code\Envs\funretire\lib\site-packages\django\contrib\gis\db\models\fields.py", line 4, in
from django.contrib.gis import forms
File "C:\Users\code\Envs\funretire\lib\site-packages\django\contrib\gis\forms__init
.py", line 2, in
from .fields import (GeometryField, GeometryCollectionField, PointField,
File "C:\Users\code\Envs\funretire\lib\site-packages\django\contrib\gis\forms\fields.py", line 11, in
from django.contrib.gis.geos import GEOSException, GEOSGeometry, fromstr
ImportError: cannot import name GEOSException

When I remove the Django-cities app from INSTALLED_APPS, manage.py syncdb seems to work just fine:

(funretire) C:\Users\code\workspace\funretire\src>python manage.py syncdb
Creating tables ...
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)

ValueError: could not convert string to float: T

Getting the output below when running manage.py cities.
Could it be a problem with python versions?

INFO Downloading: allCountries.zip
INFO Importing country data
INFO {'code': '2986043', 'postalCodeRegex': '0', 'name': '42.64991', 'codeNum': 'Pic de Font Blanca', 'area': 'T', 'geonameid': '2860', 'currencyCode': '00', 'tld': '', 'languages': '', 'phone': '', 'neighbours': 'Europe/Andorra', 'code3': 'Pic de Font Blanca', 'fips': 'Pic de Font Blanca,Pic du Port', 'capital': '1.53335', 'postalCodeFormat': '', 'currencyName': '', 'continent': 'AD', 'equivalentFips': '2014-11-05\n', 'population': 'PK'}
Traceback (most recent call last):
File "manage.py", line 10, in
execute_from_command_line(sys.argv)
File "/home/vagrant/env/local/lib/python2.7/site-packages/django/core/management/init.py", line 399, in execute_from_command_line
utility.execute()
File "/home/vagrant/env/local/lib/python2.7/site-packages/django/core/management/init.py", line 392, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/vagrant/env/local/lib/python2.7/site-packages/django/core/management/base.py", line 242, in run_from_argv
self.execute(_args, *_options.dict)
File "/home/vagrant/env/local/lib/python2.7/site-packages/django/core/management/base.py", line 285, in execute
output = self.handle(_args, *_options)
File "/home/vagrant/env/local/lib/python2.7/site-packages/cities/management/commands/cities.py", line 68, in handle
func()
File "/home/vagrant/env/local/lib/python2.7/site-packages/cities/management/commands/cities.py", line 179, in import_country
country.area = int(float(item['area'])) if item['area'] else None
ValueError: could not convert string to float: T

no 0.4 on pypi

Hey,

Can you upload 0.4 release on PyPI, 0.3 is latest..

zero length field name in format

In cities.models.create_geo_alt_names:

name_format = geo_type.name + '{}' + locale.capitalize()

..requires a positional value in the replacement field '{}', i.e. '{0}'

ImportError: cannot import name 'force_unicode' (with python 3.4)

I use django 1.7 and python 3.4

./manage.py migrate
I get this:
Traceback (most recent call last):
File "./manage.py", line 10, in
execute_from_command_line(sys.argv)
File "/home/cosmin/.v/gasit/lib/python3.4/site-packages/django/core/management/init.py", line 385, in execute_from_command_line
utility.execute()
File "/home/cosmin/.v/gasit/lib/python3.4/site-packages/django/core/management/init.py", line 354, in execute
django.setup()
File "/home/cosmin/.v/gasit/lib/python3.4/site-packages/django/init.py", line 21, in setup
apps.populate(settings.INSTALLED_APPS)
File "/home/cosmin/.v/gasit/lib/python3.4/site-packages/django/apps/registry.py", line 108, in populate
app_config.import_models(all_models)
File "/home/cosmin/.v/gasit/lib/python3.4/site-packages/django/apps/config.py", line 197, in import_models
self.models_module = import_module(models_module_name)
File "/home/cosmin/.v/gasit/lib/python3.4/importlib/init.py", line 109, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "", line 2254, in _gcd_import
File "", line 2237, in _find_and_load
File "", line 2226, in _find_and_load_unlocked
File "", line 1200, in _load_unlocked
File "", line 1129, in _exec
File "", line 1471, in exec_module
File "", line 321, in _call_with_frames_removed
File "/home/cosmin/.v/gasit/lib/python3.4/site-packages/cities/models.py", line 1, in
from django.utils.encoding import force_unicode
ImportError: cannot import name 'force_unicode'

manage.py cities fails returning "killed"

I tried to run the command on a server running with 500mb of ram, and it just fails saying "killed".

Don't know how to check the looger, but when I tried to import only the country data it worked like it should. Probably fails due to lack of memory.

import failure when manage.py cities

i have got this trace when i want to import datas

Downloading: countryInfo.txt
Importing country data
Downloading: admin1CodesASCII.txt
Building country index
Importing region 1 data
Traceback (most recent call last):
File "./manage.py", line 14, in
execute_manager(settings)
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django/core/management/init.py", line 438, in execute_manager
utility.execute()
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django/core/management/init.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django/core/management/base.py", line 191, in run_from_argv
self.execute(_args, *_options.dict)
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django/core/management/base.py", line 220, in execute
output = self.handle(_args, *_options)
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/cities/management/commands/cities.py", line 65, in handle
func()
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/cities/management/commands/cities.py", line 164, in import_region
self.import_region_0()
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/cities/management/commands/cities.py", line 218, in import_region_0
region.save()
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django/db/models/base.py", line 460, in save
self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django/db/models/base.py", line 526, in save_base
rows = manager.using(using).filter(pk=pk_val)._update(values)
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django/db/models/query.py", line 491, in _update
return query.get_compiler(self.db).execute_sql(None)
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 869, in execute_sql
cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 735, in execute_sql
cursor.execute(sql, params)
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django/db/backends/util.py", line 34, in execute
return self.cursor.execute(sql, params)
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 86, in execute
return self.cursor.execute(query, args)
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/MySQLdb/cursors.py", line 176, in execute
if not self._defer_warnings: self._warning_check()
File "/Users/odin/Developer/Projects/Django/MA/venv/lib/python2.7/site-packages/MySQLdb/cursors.py", line 92, in _warning_check
warn(w[-1], self.Warning, 3)
_mysql_exceptions.Warning: Incorrect string value: '\xCA\xBCs al...' for column 'name_std' at row 1

thank you for help

--import=region: NameError: global name 'class_' is not defined

python ./manage.py cities --settings=bookingpal.settings.staging --import=region --force

INFO File up-to-date: admin1CodesASCII.txt
INFO Building country index
INFO Importing region data
Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/var/www/bookingpal.com/releases/20140622112133/virtualenv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 399, in execute_from_command_line
    utility.execute()
  File "/var/www/bookingpal.com/releases/20140622112133/virtualenv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 392, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/var/www/bookingpal.com/releases/20140622112133/virtualenv/local/lib/python2.7/site-packages/django/core/management/base.py", line 242, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/var/www/bookingpal.com/releases/20140622112133/virtualenv/local/lib/python2.7/site-packages/django/core/management/base.py", line 285, in execute
    output = self.handle(*args, **options)
  File "/var/www/bookingpal.com/releases/20140622112133/virtualenv/local/lib/python2.7/site-packages/cities/management/commands/cities.py", line 68, in handle
    func()
  File "/var/www/bookingpal.com/releases/20140622112133/virtualenv/local/lib/python2.7/site-packages/cities/management/commands/cities.py", line 222, in import_region
    self.logger.warning("{0}: {1}: Cannot find country: {2} -- skipping".format(class_.__name__, region.name, country_code))
NameError: global name 'class_' is not defined

postal_code will not import

Hi,

I can't import=postal_code. The file allCountries.zip is downloaded but the script doesn't add a single line and nothing is displayed even with full verbose.

Tried with --force, no more luck.

Please note that my system killed the import script while importing alt_name when I first tried import=all.

I'm using PostGIS.

Any idea ?

EDIT: The module is not up to date on pip. I installed it from github. Still no postal_code after a clean install of 0.4 :(

mysql workaround distance function

It appears that mysql backend doesn't have distance() function, which is called during import process in some cases

Could we have a workaround to handle it ?

because of that, we can't sanely use mysql....

type object 'Region' has no attribute 'levels' : django-cities/cities/admin.py

Traceback (most recent call last):
File "../manage.py", line 10, in
execute_from_command_line(sys.argv)
File "/home/django/virtualenvs/site1/src/django/django/core/management/init.py", line 427, in execute_from_command_line
utility.execute()
File "/home/django/virtualenvs/site1/src/django/django/core/management/init.py", line 391, in execute
django.setup()
File "/home/django/virtualenvs/site1/src/django/django/init.py", line 21, in setup
apps.populate(settings.INSTALLED_APPS)
File "/home/django/virtualenvs/site1/src/django/django/apps/registry.py", line 112, in populate
app_config.ready()
File "/home/django/virtualenvs/site1/src/django/django/contrib/admin/apps.py", line 22, in ready
self.module.autodiscover()
File "/home/django/virtualenvs/site1/src/django/django/contrib/admin/init.py", line 23, in autodiscover
autodiscover_modules('admin', register_to=site)
File "/home/django/virtualenvs/site1/src/django/django/utils/module_loading.py", line 74, in autodiscover_modules
import_module('%s.%s' % (app_config.name, module_to_search))
File "/usr/lib/python2.7/importlib/init.py", line 37, in import_module
import(name)
File "/home/django/virtualenvs/site1/src/django-cities/cities/admin.py", line 29, in
class CityAdmin(CityBaseAdmin):
File "/home/django/virtualenvs/site1/src/django-cities/cities/admin.py", line 30, in CityAdmin
raw_id_fields = Region.levels
AttributeError: type object 'Region' has no attribute 'levels'

Large number of SQL requests when creating a form with foreignkey to django-cities

Hi,

I experience an tricky problem with creating forms with contain a dropdown menu with foreignkeys to django-cities. When the form is supposed to be created, the DB is hit with a large number of requests for 'cities_region' and 'cities_country'. Normally, I restrict the DB requests with select_related, but I do not seem to have luck with django-cities in this matter.

The model for my Item class contains the following code:

from cities.models import City
class Item(models.Model):
name = models.CharField(...)
location = models.ForeignKey(City, blank = True, null = True)
...

and the views.py contain the class based view code:

from django.views.generic.edit import CreateView, UpdateView, DeleteView
from project.models import Project
class ItemCreate(CreateView):
queryset = Item.objects.select_related('city', 'city__country', 'city__region').all()
template_name = 'item_create_form.html'

When I now request the view class, I see an unlimited number of sql requests like below hitting the db and the page is not loading. It seems that the requests are created to fill the drop down box in the form menu.

SELECT "cities_country"."id", "cities_country"."name", "cities_country"."slug", "cities_country"."code", "cities_country"."population", "cities_country"."continent", "cities_country"."tld" FROM "cities_country" WHERE "cities_country"."id" = %s
(2077456,)
SELECT "cities_region"."id", "cities_region"."name", "cities_region"."slug", "cities_region"."name_std", "cities_region"."code", "cities_region"."country_id" FROM "cities_region" WHERE "cities_region"."id" = %s
(2147291,)

How are you restricting the requests to the DB when you include foreignkeys to the django-cities app?

Thanks for your thoughts.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.