""" Hacks for the Django 1.0/1.0.2 releases. """ import django from django.conf import settings from django.db.backends.creation import BaseDatabaseCreation from django.db.models.loading import cache from django.core import management from django.core.management.commands.flush import Command as FlushCommand from django.utils.datastructures import SortedDict from south.utils.py3 import string_types class SkipFlushCommand(FlushCommand): def handle_noargs(self, **options): # no-op to avoid calling flush return class Hacks: def set_installed_apps(self, apps): """ Sets Django's INSTALLED_APPS setting to be effectively the list passed in. """ # Make sure it's a list. apps = list(apps) # Make sure it contains strings if apps: assert isinstance(apps[0], string_types), "The argument to set_installed_apps must be a list of strings." # Monkeypatch in! settings.INSTALLED_APPS, settings.OLD_INSTALLED_APPS = ( apps, settings.INSTALLED_APPS, ) self._redo_app_cache() def reset_installed_apps(self): """ Undoes the effect of set_installed_apps. """ settings.INSTALLED_APPS = settings.OLD_INSTALLED_APPS self._redo_app_cache() def _redo_app_cache(self): """ Used to repopulate AppCache after fiddling with INSTALLED_APPS. """ cache.loaded = False cache.handled = set() if django.VERSION >= (1, 6) else {} cache.postponed = [] cache.app_store = SortedDict() cache.app_models = SortedDict() cache.app_errors = {} cache._populate() def clear_app_cache(self): """ Clears the contents of AppCache to a blank state, so new models from the ORM can be added. """ self.old_app_models, cache.app_models = cache.app_models, {} def unclear_app_cache(self): """ Reversed the effects of clear_app_cache. """ cache.app_models = self.old_app_models cache._get_models_cache = {} def repopulate_app_cache(self): """ Rebuilds AppCache with the real model definitions. """ cache._populate() def store_app_cache_state(self): self.stored_app_cache_state = dict(**cache.__dict__) def restore_app_cache_state(self): cache.__dict__ = self.stored_app_cache_state def patch_flush_during_test_db_creation(self): """ Patches BaseDatabaseCreation.create_test_db to not flush database """ def patch(f): def wrapper(*args, **kwargs): # hold onto the original and replace flush command with a no-op original_flush_command = management._commands['flush'] try: management._commands['flush'] = SkipFlushCommand() # run create_test_db return f(*args, **kwargs) finally: # unpatch flush back to the original management._commands['flush'] = original_flush_command return wrapper BaseDatabaseCreation.create_test_db = patch(BaseDatabaseCreation.create_test_db)