Django

Code

Changeset 3195

Show
Ignore:
Timestamp:
06/22/06 23:37:00 (2 years ago)
Author:
russellm
Message:

Fixed #1662 -- Added resolver for string-form model references for models that have already been loaded, with tests to validate both forward and backward referenced model names. Light refactoring of model loading to make regression tests behave more like normal model loading. Also clarifies the text of some validation errors.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/core/management.py

    r3182 r3195  
    856856                rel_opts = f.rel.to._meta 
    857857                if f.rel.to not in models.get_models(): 
    858                     e.add(opts, "'%s' has relation with uninstalled model %s" % (f.name, rel_opts.object_name)) 
     858                    e.add(opts, "'%s' has relation with model %s, which has not been installed" % (f.name, rel_opts.object_name)) 
    859859 
    860860                rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name() 
     
    877877            rel_opts = f.rel.to._meta 
    878878            if f.rel.to not in models.get_models(): 
    879                 e.add(opts, "'%s' has m2m relation with uninstalled model %s" % (f.name, rel_opts.object_name)) 
     879                e.add(opts, "'%s' has m2m relation with model %s, which has not been installed" % (f.name, rel_opts.object_name)) 
    880880 
    881881            rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name() 
  • django/trunk/django/db/models/fields/related.py

    r3113 r3195  
    11from django.db import backend, connection, transaction 
    2 from django.db.models import signals 
     2from django.db.models import signals, get_model 
    33from django.db.models.fields import AutoField, Field, IntegerField, get_ul_class 
    44from django.db.models.related import RelatedObject 
     
    2424    module = rel_cls.__module__ 
    2525    key = (module, name) 
    26     pending_lookups.setdefault(key, []).append((rel_cls, field)) 
     26    model = get_model(rel_cls._meta.app_label,field.rel.to) 
     27    if model: 
     28        field.rel.to = model 
     29        field.do_related_class(model, rel_cls) 
     30    else: 
     31        pending_lookups.setdefault(key, []).append((rel_cls, field)) 
    2732 
    2833def do_pending_lookups(sender): 
  • django/trunk/django/db/models/loading.py

    r2995 r3195  
    66__all__ = ('get_apps', 'get_app', 'get_models', 'get_model', 'register_models') 
    77 
    8 _app_list = None # Cache of installed apps. 
     8_app_list = []   # Cache of installed apps. 
     9                 # Entry is not placed in app_list cache until entire app is loaded. 
    910_app_models = {} # Dictionary of models against app label 
    1011                 # Each value is a dictionary of model name: model class 
     12                 # Applabel and Model entry exists in cache when individual model is loaded. 
     13_loaded = False  # Has the contents of settings.INSTALLED_APPS been loaded?  
     14                 # i.e., has get_apps() been called? 
    1115 
    1216def get_apps(): 
    1317    "Returns a list of all installed modules that contain models." 
    1418    global _app_list 
    15     if _app_list is not None: 
    16         return _app_list 
    17     _app_list = [] 
    18     for app_name in settings.INSTALLED_APPS: 
    19         try: 
    20             mod = __import__(app_name, '', '', ['models']) 
    21         except ImportError: 
    22             pass # Assume this app doesn't have a models.py in it. 
    23                  # GOTCHA: It may have a models.py that raises ImportError. 
    24         else: 
     19    global _loaded 
     20    if not _loaded: 
     21        _loaded = True 
     22        for app_name in settings.INSTALLED_APPS: 
    2523            try: 
    26                 _app_list.append(mod.models) 
     24                load_app(app_name) 
     25            except ImportError: 
     26                pass # Assume this app doesn't have a models.py in it. 
     27                     # GOTCHA: It may have a models.py that raises ImportError. 
    2728            except AttributeError: 
    2829                pass # This app doesn't have a models.py in it. 
     
    3132def get_app(app_label): 
    3233    "Returns the module containing the models for the given app_label." 
     34    get_apps() # Run get_apps() to populate the _app_list cache. Slightly hackish. 
    3335    for app_name in settings.INSTALLED_APPS: 
    3436        if app_label == app_name.split('.')[-1]: 
    35             return __import__(app_name, '', '', ['models']).models 
     37            return load_app(app_name) 
    3638    raise ImproperlyConfigured, "App with label %s could not be found" % app_label 
    3739 
     40def load_app(app_name): 
     41    "Loads the app with the provided fully qualified name, and returns the model module." 
     42    mod = __import__(app_name, '', '', ['models']) 
     43    if mod.models not in _app_list: 
     44        _app_list.append(mod.models) 
     45    return mod.models 
     46     
    3847def get_models(app_mod=None): 
    3948    """ 
  • django/trunk/tests/runtests.py

    r3181 r3195  
    163163        cursor = connection.cursor() 
    164164 
     165        from django.db.models.loading import load_app 
    165166        # Install the core always installed apps 
    166167        for app in ALWAYS_INSTALLED_APPS: 
    167168            self.output(1, "Installing contrib app %s" % app) 
    168             mod = __import__(app + ".models", '', '', ['']
     169            mod = load_app(app
    169170            management.install(mod) 
    170171 
     
    174175            self.output(1, "%s model: Importing" % model_name) 
    175176            try: 
    176                 # TODO: Abstract this into a meta.get_app() replacement? 
    177                 mod = __import__(model_dir + '.' + model_name + '.models', '', '', ['']) 
     177                mod = load_app(model_dir + '.' + model_name) 
    178178            except Exception, e: 
    179179                log_error(model_name, "Error while importing", ''.join(traceback.format_exception(*sys.exc_info())[1:]))