Source code for cities_light.receivers

from django.db.models import signals
from .abstract_models import to_ascii, to_search
from .settings import *
from .signals import *
from .exceptions import *


def set_name_ascii(sender, instance=None, **kwargs):
    """
    Signal reciever that sets instance.name_ascii from instance.name.

    Ascii versions of names are often useful for autocompletes and search.
    """
    name_ascii = to_ascii(instance.name)

    if not name_ascii.strip():
        return

    if name_ascii and not instance.name_ascii:
        instance.name_ascii = to_ascii(instance.name)


def set_display_name(sender, instance=None, **kwargs):
    """
    Set instance.display_name to instance.get_display_name(), avoid spawning
    queries during __str__().
    """
    instance.display_name = instance.get_display_name()


def city_country(sender, instance, **kwargs):
    if instance.region_id and not instance.country_id:
        instance.country = instance.region.country


def city_search_names(sender, instance, **kwargs):
    search_names = set()

    country_names = set((instance.country.name,))
    if instance.country.alternate_names:
        for n in instance.country.alternate_names.split(','):
            country_names.add(n)

    city_names = set((instance.name,))
    if instance.alternate_names:
        for n in instance.alternate_names.split(','):
            city_names.add(n)

    if instance.region_id:
        region_names = set((instance.region.name,))
        if instance.region.alternate_names:
            for n in instance.region.alternate_names.split(','):
                region_names.add(n)

    for city_name in city_names:
        for country_name in country_names:
            name = to_search(city_name + country_name)
            search_names.add(name)

            if instance.region_id:
                for region_name in region_names:
                    name = to_search(city_name + region_name + country_name)
                    search_names.add(name)

    instance.search_names = ' '.join(sorted(search_names))


def connect_default_signals(model_class):
    """
    Use this function to connect default signals to your custom model.
    It is called automatically, if default cities_light models are used,
    i.e. settings `CITIES_LIGHT_APP_NAME` is not changed.
    """
    if 'Country' in model_class.__name__:
        signals.pre_save.connect(set_name_ascii, sender=model_class)
    if 'Region' in model_class.__name__:
        signals.pre_save.connect(set_name_ascii, sender=model_class)
        signals.pre_save.connect(set_display_name, sender=model_class)
    if 'City' in model_class.__name__:
        signals.pre_save.connect(set_name_ascii, sender=model_class)
        signals.pre_save.connect(set_display_name, sender=model_class)
        signals.pre_save.connect(city_country, sender=model_class)
        signals.pre_save.connect(city_search_names, sender=model_class)


[docs]def filter_non_cities(sender, items, **kwargs): """ Exclude any **city** which feature code must not be included. By default, this receiver is connected to :py:func:`~cities_light.signals.city_items_pre_import`, it raises :py:class:`~cities_light.exceptions.InvalidItems` if the row feature code is not in the :py:data:`~cities_light.settings.INCLUDE_CITY_TYPES` setting. """ if items[7] not in INCLUDE_CITY_TYPES: raise InvalidItems()
city_items_pre_import.connect(filter_non_cities)
[docs]def filter_non_included_countries_country(sender, items, **kwargs): """ Exclude any **country** which country must not be included. This is slot is connected to the :py:func:`~cities_light.signals.country_items_pre_import` signal and does nothing by default. To enable it, set the :py:data:`~cities_light.settings.INCLUDE_COUNTRIES` setting. """ if INCLUDE_COUNTRIES is None: return if items[0].split('.')[0] not in INCLUDE_COUNTRIES: raise InvalidItems()
country_items_pre_import.connect(filter_non_included_countries_country)
[docs]def filter_non_included_countries_region(sender, items, **kwargs): """ Exclude any **region** which country must not be included. This is slot is connected to the :py:func:`~cities_light.signals.region_items_pre_import` signal and does nothing by default. To enable it, set the :py:data:`~cities_light.settings.INCLUDE_COUNTRIES` setting. """ if INCLUDE_COUNTRIES is None: return if items[0].split('.')[0] not in INCLUDE_COUNTRIES: raise InvalidItems()
region_items_pre_import.connect(filter_non_included_countries_region)
[docs]def filter_non_included_countries_city(sender, items, **kwargs): """ Exclude any **city** which country must not be included. This is slot is connected to the :py:func:`~cities_light.signals.city_items_pre_import` signal and does nothing by default. To enable it, set the :py:data:`~cities_light.settings.INCLUDE_COUNTRIES` setting. """ if INCLUDE_COUNTRIES is None: return if items[8].split('.')[0] not in INCLUDE_COUNTRIES: raise InvalidItems()
city_items_pre_import.connect(filter_non_included_countries_city)