web/lib/django/db/models/loading.py
author ymh <ymh.work@gmail.com>
Tue, 15 Mar 2011 10:34:41 +0100
changeset 65 3d18d15135f1
parent 38 77b6da96e6f1
permissions -rw-r--r--
put video url in segment object
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
38
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
"Utilities for loading models and the modules that contain them."
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
from django.conf import settings
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
from django.core.exceptions import ImproperlyConfigured
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
from django.utils.datastructures import SortedDict
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
from django.utils.importlib import import_module
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
from django.utils.module_loading import module_has_submodule
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
import imp
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
import sys
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
import os
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
import threading
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
__all__ = ('get_apps', 'get_app', 'get_models', 'get_model', 'register_models',
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
        'load_app', 'app_cache_ready')
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
class AppCache(object):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
    """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
    A cache that stores installed applications and their models. Used to
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
    provide reverse-relations and for app introspection (e.g. admin).
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
    """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
    # Use the Borg pattern to share state between all instances. Details at
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
    # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66531.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
    __shared_state = dict(
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
        # Keys of app_store are the model modules for each application.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
        app_store = SortedDict(),
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
        # Mapping of app_labels to a dictionary of model names to model code.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
        app_models = SortedDict(),
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
        # Mapping of app_labels to errors raised when trying to import the app.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
        app_errors = {},
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
        # -- Everything below here is only used when populating the cache --
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
        loaded = False,
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
        handled = {},
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
        postponed = [],
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
        nesting_level = 0,
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
        write_lock = threading.RLock(),
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
        _get_models_cache = {},
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
    )
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
    def __init__(self):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
        self.__dict__ = self.__shared_state
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
    def _populate(self):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
        Fill in all the cache information. This method is threadsafe, in the
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
        sense that every caller will see the same state upon return, and if the
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
        cache is already initialised, it does no work.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
        if self.loaded:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
            return
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
        self.write_lock.acquire()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
        try:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
            if self.loaded:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
                return
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
            for app_name in settings.INSTALLED_APPS:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
                if app_name in self.handled:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
                    continue
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
                self.load_app(app_name, True)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
            if not self.nesting_level:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
                for app_name in self.postponed:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
                    self.load_app(app_name)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
                self.loaded = True
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
        finally:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
            self.write_lock.release()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
    def load_app(self, app_name, can_postpone=False):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
        Loads the app with the provided fully qualified name, and returns the
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
        model module.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
        self.handled[app_name] = None
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
        self.nesting_level += 1
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
        app_module = import_module(app_name)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
        try:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
            models = import_module('.models', app_name)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
        except ImportError:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
            self.nesting_level -= 1
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
            # If the app doesn't have a models module, we can just ignore the
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
            # ImportError and return no models for it.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
            if not module_has_submodule(app_module, 'models'):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
                return None
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
            # But if the app does have a models module, we need to figure out
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
            # whether to suppress or propagate the error. If can_postpone is
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
            # True then it may be that the package is still being imported by
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
            # Python and the models module isn't available yet. So we add the
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
            # app to the postponed list and we'll try it again after all the
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
            # recursion has finished (in populate). If can_postpone is False
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
            # then it's time to raise the ImportError.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
            else:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
                if can_postpone:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
                    self.postponed.append(app_name)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
                    return None
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
                else:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
                    raise
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
        self.nesting_level -= 1
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
        if models not in self.app_store:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
            self.app_store[models] = len(self.app_store)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
        return models
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   103
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
    def app_cache_ready(self):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
        Returns true if the model cache is fully populated.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
        Useful for code that wants to cache the results of get_models() for
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
        themselves once it is safe to do so.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
        return self.loaded
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
    def get_apps(self):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
        "Returns a list of all installed modules that contain models."
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
        self._populate()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
        # Ensure the returned list is always in the same order (with new apps
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
        # added at the end). This avoids unstable ordering on the admin app
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
        # list page, for example.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
        apps = [(v, k) for k, v in self.app_store.items()]
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
        apps.sort()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
        return [elt[1] for elt in apps]
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
    def get_app(self, app_label, emptyOK=False):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   125
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
        Returns the module containing the models for the given app_label. If
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
        the app has no models in it and 'emptyOK' is True, returns None.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   128
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   129
        self._populate()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   130
        self.write_lock.acquire()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   131
        try:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   132
            for app_name in settings.INSTALLED_APPS:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   133
                if app_label == app_name.split('.')[-1]:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   134
                    mod = self.load_app(app_name, False)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   135
                    if mod is None:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   136
                        if emptyOK:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   137
                            return None
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   138
                    else:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   139
                        return mod
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   140
            raise ImproperlyConfigured("App with label %s could not be found" % app_label)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   141
        finally:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   142
            self.write_lock.release()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   143
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   144
    def get_app_errors(self):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   145
        "Returns the map of known problems with the INSTALLED_APPS."
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   146
        self._populate()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   147
        return self.app_errors
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   148
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   149
    def get_models(self, app_mod=None, include_auto_created=False, include_deferred=False):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   150
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   151
        Given a module containing models, returns a list of the models.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   152
        Otherwise returns a list of all installed models.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   153
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   154
        By default, auto-created models (i.e., m2m models without an
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   155
        explicit intermediate table) are not included. However, if you
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   156
        specify include_auto_created=True, they will be.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   157
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   158
        By default, models created to satisfy deferred attribute
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   159
        queries are *not* included in the list of models. However, if
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   160
        you specify include_deferred, they will be.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   161
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   162
        cache_key = (app_mod, include_auto_created, include_deferred)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   163
        try:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   164
            return self._get_models_cache[cache_key]
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   165
        except KeyError:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   166
            pass
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   167
        self._populate()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   168
        if app_mod:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   169
            app_list = [self.app_models.get(app_mod.__name__.split('.')[-2], SortedDict())]
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   170
        else:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   171
            app_list = self.app_models.itervalues()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   172
        model_list = []
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   173
        for app in app_list:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   174
            model_list.extend(
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   175
                model for model in app.values()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   176
                if ((not model._deferred or include_deferred)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   177
                    and (not model._meta.auto_created or include_auto_created))
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   178
            )
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   179
        self._get_models_cache[cache_key] = model_list
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   180
        return model_list
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   181
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   182
    def get_model(self, app_label, model_name, seed_cache=True):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   183
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   184
        Returns the model matching the given app_label and case-insensitive
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   185
        model_name.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   186
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   187
        Returns None if no model is found.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   188
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   189
        if seed_cache:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   190
            self._populate()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   191
        return self.app_models.get(app_label, SortedDict()).get(model_name.lower())
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   192
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   193
    def register_models(self, app_label, *models):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   194
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   195
        Register a set of models as belonging to an app.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   196
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   197
        for model in models:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   198
            # Store as 'name: model' pair in a dictionary
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   199
            # in the app_models dictionary
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   200
            model_name = model._meta.object_name.lower()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   201
            model_dict = self.app_models.setdefault(app_label, SortedDict())
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   202
            if model_name in model_dict:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   203
                # The same model may be imported via different paths (e.g.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   204
                # appname.models and project.appname.models). We use the source
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   205
                # filename as a means to detect identity.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   206
                fname1 = os.path.abspath(sys.modules[model.__module__].__file__)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   207
                fname2 = os.path.abspath(sys.modules[model_dict[model_name].__module__].__file__)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   208
                # Since the filename extension could be .py the first time and
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   209
                # .pyc or .pyo the second time, ignore the extension when
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   210
                # comparing.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   211
                if os.path.splitext(fname1)[0] == os.path.splitext(fname2)[0]:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   212
                    continue
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   213
            model_dict[model_name] = model
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   214
        self._get_models_cache.clear()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   215
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   216
cache = AppCache()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   217
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   218
# These methods were always module level, so are kept that way for backwards
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   219
# compatibility.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   220
get_apps = cache.get_apps
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   221
get_app = cache.get_app
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   222
get_app_errors = cache.get_app_errors
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   223
get_models = cache.get_models
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   224
get_model = cache.get_model
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   225
register_models = cache.register_models
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   226
load_app = cache.load_app
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   227
app_cache_ready = cache.app_cache_ready