Commits

Andrew Godwin committed b996f6d

Much better AppCache and ORM handling, so M2Ms resolve backwards correctly (also moved AppCache fiddling into hacks)

Comments (0)

Files changed (2)

south/hacks/django_1_0.py

 
 from django.conf import settings
 from django.db import models
+from django.db.models.loading import AppCache, cache
 
 class Hacks:
     
         """
         Used to repopulate AppCache after fiddling with INSTALLED_APPS.
         """
-        from django.db.models.loading import AppCache
         a = AppCache()
         a.loaded = False
-        a._populate()
+        a._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
+    
 
 from south.db import db
 from south.utils import ask_for_it_by_name
+from south.hacks import hacks
 
 
 class ModelsLocals(object):
         except AttributeError:
             return
         
+        # Start a 'new' AppCache
+        hacks.clear_app_cache()
+        
         # Now, make each model's data into a FakeModel
         for name, data in self.models_source.items():
             # Make sure there's some kind of Meta
         
         # And perform the second run to iron out any circular/backwards depends.
         self.retry_failed_fields()
+        
+        # Force evaluation of relations on the models now
+        for model in self.models.values():
+            model._meta.get_all_field_names()
+        
+        # Reset AppCache
+        hacks.unclear_app_cache()
 
     
     def __getattr__(self, key):
         
         more_kwds['Meta'] = meta
         
-        # Stop AppCache from changing!
-        cache.app_models[app], old_app_models = {}, cache.app_models.get(app, {})
-        
         # Make our model
         fields.update(more_kwds)
         
             fields,
         )
         
-        # Send AppCache back in time
-        cache.app_models[app] = old_app_models
-        
         # If this is a stub model, change Objects to a whiny class
         if stub:
             model.objects = WhinyManager()