from django.conf import settings from django.core.exceptions import ImproperlyConfigured _prefixes = {} def swappable_setting(app_label, model): """ Returns the setting name to use for the given model (i.e. AUTH_USER_MODEL) """ prefix = _prefixes.get(app_label, app_label) setting = "{prefix}_{model}_MODEL".format( prefix=prefix.upper(), model=model.upper() ) # Ensure this attribute exists to avoid migration issues in Django 1.7 if not hasattr(settings, setting): setattr(settings, setting, join(app_label, model)) return setting def is_swapped(app_label, model): """ Returns the value of the swapped setting, or False if the model hasn't been swapped. """ default_model = join(app_label, model) setting = swappable_setting(app_label, model) value = getattr(settings, setting, default_model) if value != default_model: return value else: return False def get_model_name(app_label, model): """ Returns [app_label.model] unless the model has been swapped, in which case returns the swappable setting value. """ return is_swapped(app_label, model) or join(app_label, model) def dependency(app_label, model): """ Returns a Django 1.7+ style dependency tuple for inclusion in migration.dependencies[] """ from django.db.migrations import swappable_dependency return swappable_dependency(get_model_name(app_label, model)) def get_model_names(app_label, models): """ Map model names to their swapped equivalents for the given app """ return dict( (model, get_model_name(app_label, model)) for model in models ) def load_model(app_label, model, orm=None, required=True): """ Load the specified model class, or the class it was swapped out for. If a South orm object is provided, it will be used (but only if the model hasn't been swapped.) """ swapped = is_swapped(app_label, model) if swapped: app_label, model = split(swapped) else: if orm is not None: return orm[join(app_label, model)] try: try: # django >= 1.7 from django.apps import apps cls = apps.get_model(app_label, model) except ImportError: # django < 1.7 from django.db.models import get_model cls = get_model(app_label, model) except LookupError: # both get_model versions can raise a LookupError cls = None if cls is None and required: raise ImproperlyConfigured( "Could not find {name}!".format(name=join(app_label, model)) ) return cls def set_app_prefix(app_label, prefix): """ Set a custom prefix to use for the given app (e.g. WQ) """ _prefixes[app_label] = prefix def join(app_label, model): return "{app_label}.{model}".format( app_label=app_label, model=model, ) def split(model): app_label, _, model = model.rpartition(".") return app_label, model