<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang=""> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>django.apps.registry — Django 1.8.19 documentation</title> <link rel="stylesheet" href="../../../_static/default.css" type="text/css" /> <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../../../', VERSION: '1.8.19', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../../../_static/jquery.js"></script> <script type="text/javascript" src="../../../_static/underscore.js"></script> <script type="text/javascript" src="../../../_static/doctools.js"></script> <link rel="index" title="Index" href="../../../genindex.html" /> <link rel="search" title="Search" href="../../../search.html" /> <link rel="top" title="Django 1.8.19 documentation" href="../../../contents.html" /> <link rel="up" title="django" href="../../django.html" /> <script type="text/javascript" src="../../../templatebuiltins.js"></script> <script type="text/javascript"> (function($) { if (!django_template_builtins) { // templatebuiltins.js missing, do nothing. return; } $(document).ready(function() { // Hyperlink Django template tags and filters var base = "../../../ref/templates/builtins.html"; if (base == "#") { // Special case for builtins.html itself base = ""; } // Tags are keywords, class '.k' $("div.highlight\\-html\\+django span.k").each(function(i, elem) { var tagname = $(elem).text(); if ($.inArray(tagname, django_template_builtins.ttags) != -1) { var fragment = tagname.replace(/_/, '-'); $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>"); } }); // Filters are functions, class '.nf' $("div.highlight\\-html\\+django span.nf").each(function(i, elem) { var filtername = $(elem).text(); if ($.inArray(filtername, django_template_builtins.tfilters) != -1) { var fragment = filtername.replace(/_/, '-'); $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>"); } }); }); })(jQuery); </script> </head> <body role="document"> <div class="document"> <div id="custom-doc" class="yui-t6"> <div id="hd"> <h1><a href="../../../index.html">Django 1.8.19 documentation</a></h1> <div id="global-nav"> <a title="Home page" href="../../../index.html">Home</a> | <a title="Table of contents" href="../../../contents.html">Table of contents</a> | <a title="Global index" href="../../../genindex.html">Index</a> | <a title="Module index" href="../../../py-modindex.html">Modules</a> </div> <div class="nav"> <a href="../../index.html" title="Module code" accesskey="U">up</a></div> </div> <div id="bd"> <div id="yui-main"> <div class="yui-b"> <div class="yui-g" id="_modules-django-apps-registry"> <h1>Source code for django.apps.registry</h1><div class="highlight"><pre> <span></span><span class="kn">import</span> <span class="nn">os</span> <span class="kn">import</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="nn">threading</span> <span class="kn">import</span> <span class="nn">warnings</span> <span class="kn">from</span> <span class="nn">collections</span> <span class="k">import</span> <span class="n">Counter</span><span class="p">,</span> <span class="n">OrderedDict</span><span class="p">,</span> <span class="n">defaultdict</span> <span class="kn">from</span> <span class="nn">django.core.exceptions</span> <span class="k">import</span> <span class="n">AppRegistryNotReady</span><span class="p">,</span> <span class="n">ImproperlyConfigured</span> <span class="kn">from</span> <span class="nn">django.utils</span> <span class="k">import</span> <span class="n">lru_cache</span> <span class="kn">from</span> <span class="nn">django.utils._os</span> <span class="k">import</span> <span class="n">upath</span> <span class="kn">from</span> <span class="nn">django.utils.deprecation</span> <span class="k">import</span> <span class="n">RemovedInDjango19Warning</span> <span class="kn">from</span> <span class="nn">.config</span> <span class="k">import</span> <span class="n">AppConfig</span> <span class="k">class</span> <span class="nc">Apps</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> A registry that stores the configuration of installed applications.</span> <span class="sd"> It also keeps track of models eg. to provide reverse-relations.</span> <span class="sd"> """</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">installed_apps</span><span class="o">=</span><span class="p">()):</span> <span class="c1"># installed_apps is set to None when creating the master registry</span> <span class="c1"># because it cannot be populated at that point. Other registries must</span> <span class="c1"># provide a list of installed apps and are populated immediately.</span> <span class="k">if</span> <span class="n">installed_apps</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="n">__name__</span><span class="p">],</span> <span class="s1">'apps'</span><span class="p">):</span> <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"You must supply an installed_apps argument."</span><span class="p">)</span> <span class="c1"># Mapping of app labels => model names => model classes. Every time a</span> <span class="c1"># model is imported, ModelBase.__new__ calls apps.register_model which</span> <span class="c1"># creates an entry in all_models. All imported models are registered,</span> <span class="c1"># regardless of whether they're defined in an installed application</span> <span class="c1"># and whether the registry has been populated. Since it isn't possible</span> <span class="c1"># to reimport a module safely (it could reexecute initialization code)</span> <span class="c1"># all_models is never overridden or reset.</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_models</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="n">OrderedDict</span><span class="p">)</span> <span class="c1"># Mapping of labels to AppConfig instances for installed apps.</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="p">()</span> <span class="c1"># Stack of app_configs. Used to store the current state in</span> <span class="c1"># set_available_apps and set_installed_apps.</span> <span class="bp">self</span><span class="o">.</span><span class="n">stored_app_configs</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># Whether the registry is populated.</span> <span class="bp">self</span><span class="o">.</span><span class="n">apps_ready</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">models_ready</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ready</span> <span class="o">=</span> <span class="kc">False</span> <span class="c1"># Lock for thread-safe population.</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lock</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Lock</span><span class="p">()</span> <span class="c1"># Pending lookups for lazy relations.</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_lookups</span> <span class="o">=</span> <span class="p">{}</span> <span class="c1"># Populate apps and models, unless it's the master registry.</span> <span class="k">if</span> <span class="n">installed_apps</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">populate</span><span class="p">(</span><span class="n">installed_apps</span><span class="p">)</span> <span class="k">def</span> <span class="nf">populate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">installed_apps</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Loads application configurations and models.</span> <span class="sd"> This method imports each application module and then each model module.</span> <span class="sd"> It is thread safe and idempotent, but not reentrant.</span> <span class="sd"> """</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">ready</span><span class="p">:</span> <span class="k">return</span> <span class="c1"># populate() might be called by two threads in parallel on servers</span> <span class="c1"># that create threads before initializing the WSGI callable.</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lock</span><span class="p">:</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">ready</span><span class="p">:</span> <span class="k">return</span> <span class="c1"># app_config should be pristine, otherwise the code below won't</span> <span class="c1"># guarantee that the order matches the order in INSTALLED_APPS.</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span><span class="p">:</span> <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"populate() isn't reentrant"</span><span class="p">)</span> <span class="c1"># Load app configs and app modules.</span> <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">installed_apps</span><span class="p">:</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="n">AppConfig</span><span class="p">):</span> <span class="n">app_config</span> <span class="o">=</span> <span class="n">entry</span> <span class="k">else</span><span class="p">:</span> <span class="n">app_config</span> <span class="o">=</span> <span class="n">AppConfig</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">entry</span><span class="p">)</span> <span class="k">if</span> <span class="n">app_config</span><span class="o">.</span><span class="n">label</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span><span class="p">:</span> <span class="k">raise</span> <span class="n">ImproperlyConfigured</span><span class="p">(</span> <span class="s2">"Application labels aren't unique, "</span> <span class="s2">"duplicates: </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">app_config</span><span class="o">.</span><span class="n">label</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span><span class="p">[</span><span class="n">app_config</span><span class="o">.</span><span class="n">label</span><span class="p">]</span> <span class="o">=</span> <span class="n">app_config</span> <span class="c1"># Check for duplicate app names.</span> <span class="n">counts</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span> <span class="n">app_config</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">app_config</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span><span class="o">.</span><span class="n">values</span><span class="p">())</span> <span class="n">duplicates</span> <span class="o">=</span> <span class="p">[</span> <span class="n">name</span> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">count</span> <span class="ow">in</span> <span class="n">counts</span><span class="o">.</span><span class="n">most_common</span><span class="p">()</span> <span class="k">if</span> <span class="n">count</span> <span class="o">></span> <span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="n">duplicates</span><span class="p">:</span> <span class="k">raise</span> <span class="n">ImproperlyConfigured</span><span class="p">(</span> <span class="s2">"Application names aren't unique, "</span> <span class="s2">"duplicates: </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">duplicates</span><span class="p">))</span> <span class="bp">self</span><span class="o">.</span><span class="n">apps_ready</span> <span class="o">=</span> <span class="kc">True</span> <span class="c1"># Load models.</span> <span class="k">for</span> <span class="n">app_config</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> <span class="n">all_models</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_models</span><span class="p">[</span><span class="n">app_config</span><span class="o">.</span><span class="n">label</span><span class="p">]</span> <span class="n">app_config</span><span class="o">.</span><span class="n">import_models</span><span class="p">(</span><span class="n">all_models</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">clear_cache</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">models_ready</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">for</span> <span class="n">app_config</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_app_configs</span><span class="p">():</span> <span class="n">app_config</span><span class="o">.</span><span class="n">ready</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">ready</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">def</span> <span class="nf">check_apps_ready</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Raises an exception if all apps haven't been imported yet.</span> <span class="sd"> """</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">apps_ready</span><span class="p">:</span> <span class="k">raise</span> <span class="n">AppRegistryNotReady</span><span class="p">(</span><span class="s2">"Apps aren't loaded yet."</span><span class="p">)</span> <span class="k">def</span> <span class="nf">check_models_ready</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Raises an exception if all models haven't been imported yet.</span> <span class="sd"> """</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">models_ready</span><span class="p">:</span> <span class="k">raise</span> <span class="n">AppRegistryNotReady</span><span class="p">(</span><span class="s2">"Models aren't loaded yet."</span><span class="p">)</span> <span class="k">def</span> <span class="nf">get_app_configs</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Imports applications and returns an iterable of app configs.</span> <span class="sd"> """</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_apps_ready</span><span class="p">()</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span><span class="o">.</span><span class="n">values</span><span class="p">()</span> <span class="k">def</span> <span class="nf">get_app_config</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app_label</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Imports applications and returns an app config for the given label.</span> <span class="sd"> Raises LookupError if no application exists with this label.</span> <span class="sd"> """</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_apps_ready</span><span class="p">()</span> <span class="k">try</span><span class="p">:</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span><span class="p">[</span><span class="n">app_label</span><span class="p">]</span> <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> <span class="k">raise</span> <span class="ne">LookupError</span><span class="p">(</span><span class="s2">"No installed app with label '</span><span class="si">%s</span><span class="s2">'."</span> <span class="o">%</span> <span class="n">app_label</span><span class="p">)</span> <span class="c1"># This method is performance-critical at least for Django's test suite.</span> <span class="nd">@lru_cache</span><span class="o">.</span><span class="n">lru_cache</span><span class="p">(</span><span class="n">maxsize</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span> <span class="k">def</span> <span class="nf">get_models</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app_mod</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">include_auto_created</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">include_deferred</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">include_swapped</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Returns a list of all installed models.</span> <span class="sd"> By default, the following models aren't included:</span> <span class="sd"> - auto-created models for many-to-many relations without</span> <span class="sd"> an explicit intermediate table,</span> <span class="sd"> - models created to satisfy deferred attribute queries,</span> <span class="sd"> - models that have been swapped out.</span> <span class="sd"> Set the corresponding keyword argument to True to include such models.</span> <span class="sd"> """</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_models_ready</span><span class="p">()</span> <span class="k">if</span> <span class="n">app_mod</span><span class="p">:</span> <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span> <span class="s2">"The app_mod argument of get_models is deprecated."</span><span class="p">,</span> <span class="n">RemovedInDjango19Warning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="n">app_label</span> <span class="o">=</span> <span class="n">app_mod</span><span class="o">.</span><span class="n">__name__</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> <span class="k">try</span><span class="p">:</span> <span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_app_config</span><span class="p">(</span><span class="n">app_label</span><span class="p">)</span><span class="o">.</span><span class="n">get_models</span><span class="p">(</span> <span class="n">include_auto_created</span><span class="p">,</span> <span class="n">include_deferred</span><span class="p">,</span> <span class="n">include_swapped</span><span class="p">))</span> <span class="k">except</span> <span class="ne">LookupError</span><span class="p">:</span> <span class="k">return</span> <span class="p">[]</span> <span class="n">result</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">app_config</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> <span class="n">result</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">app_config</span><span class="o">.</span><span class="n">get_models</span><span class="p">(</span> <span class="n">include_auto_created</span><span class="p">,</span> <span class="n">include_deferred</span><span class="p">,</span> <span class="n">include_swapped</span><span class="p">)))</span> <span class="k">return</span> <span class="n">result</span> <span class="k">def</span> <span class="nf">get_model</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app_label</span><span class="p">,</span> <span class="n">model_name</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Returns the model matching the given app_label and model_name.</span> <span class="sd"> As a shortcut, this function also accepts a single argument in the</span> <span class="sd"> form <app_label>.<model_name>.</span> <span class="sd"> model_name is case-insensitive.</span> <span class="sd"> Raises LookupError if no application exists with this label, or no</span> <span class="sd"> model exists with this name in the application. Raises ValueError if</span> <span class="sd"> called with a single argument that doesn't contain exactly one dot.</span> <span class="sd"> """</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_models_ready</span><span class="p">()</span> <span class="k">if</span> <span class="n">model_name</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">app_label</span><span class="p">,</span> <span class="n">model_name</span> <span class="o">=</span> <span class="n">app_label</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_app_config</span><span class="p">(</span><span class="n">app_label</span><span class="p">)</span><span class="o">.</span><span class="n">get_model</span><span class="p">(</span><span class="n">model_name</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span> <span class="k">def</span> <span class="nf">register_model</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app_label</span><span class="p">,</span> <span class="n">model</span><span class="p">):</span> <span class="c1"># Since this method is called when models are imported, it cannot</span> <span class="c1"># perform imports because of the risk of import loops. It mustn't</span> <span class="c1"># call get_app_config().</span> <span class="n">model_name</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">model_name</span> <span class="n">app_models</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_models</span><span class="p">[</span><span class="n">app_label</span><span class="p">]</span> <span class="k">if</span> <span class="n">model_name</span> <span class="ow">in</span> <span class="n">app_models</span><span class="p">:</span> <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="o">.</span><span class="n">__name__</span> <span class="o">==</span> <span class="n">app_models</span><span class="p">[</span><span class="n">model_name</span><span class="p">]</span><span class="o">.</span><span class="n">__name__</span> <span class="ow">and</span> <span class="n">model</span><span class="o">.</span><span class="n">__module__</span> <span class="o">==</span> <span class="n">app_models</span><span class="p">[</span><span class="n">model_name</span><span class="p">]</span><span class="o">.</span><span class="n">__module__</span><span class="p">):</span> <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span> <span class="s2">"Model '</span><span class="si">%s</span><span class="s2">.</span><span class="si">%s</span><span class="s2">' was already registered. "</span> <span class="s2">"Reloading models is not advised as it can lead to inconsistencies, "</span> <span class="s2">"most notably with related models."</span> <span class="o">%</span> <span class="p">(</span><span class="n">app_label</span><span class="p">,</span> <span class="n">model_name</span><span class="p">),</span> <span class="ne">RuntimeWarning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> <span class="s2">"Conflicting '</span><span class="si">%s</span><span class="s2">' models in application '</span><span class="si">%s</span><span class="s2">': </span><span class="si">%s</span><span class="s2"> and </span><span class="si">%s</span><span class="s2">."</span> <span class="o">%</span> <span class="p">(</span><span class="n">model_name</span><span class="p">,</span> <span class="n">app_label</span><span class="p">,</span> <span class="n">app_models</span><span class="p">[</span><span class="n">model_name</span><span class="p">],</span> <span class="n">model</span><span class="p">))</span> <span class="n">app_models</span><span class="p">[</span><span class="n">model_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">model</span> <span class="bp">self</span><span class="o">.</span><span class="n">clear_cache</span><span class="p">()</span> <span class="k">def</span> <span class="nf">is_installed</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app_name</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Checks whether an application with this name exists in the registry.</span> <span class="sd"> app_name is the full name of the app eg. 'django.contrib.admin'.</span> <span class="sd"> """</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_apps_ready</span><span class="p">()</span> <span class="k">return</span> <span class="nb">any</span><span class="p">(</span><span class="n">ac</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="n">app_name</span> <span class="k">for</span> <span class="n">ac</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span><span class="o">.</span><span class="n">values</span><span class="p">())</span> <span class="k">def</span> <span class="nf">get_containing_app_config</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">object_name</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Look for an app config containing a given object.</span> <span class="sd"> object_name is the dotted Python path to the object.</span> <span class="sd"> Returns the app config for the inner application in case of nesting.</span> <span class="sd"> Returns None if the object isn't in any registered app config.</span> <span class="sd"> """</span> <span class="c1"># In Django 1.7 and 1.8, it's allowed to call this method at import</span> <span class="c1"># time, even while the registry is being populated. In Django 1.9 and</span> <span class="c1"># later, that should be forbidden with `self.check_apps_ready()`.</span> <span class="n">candidates</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">app_config</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> <span class="k">if</span> <span class="n">object_name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">app_config</span><span class="o">.</span><span class="n">name</span><span class="p">):</span> <span class="n">subpath</span> <span class="o">=</span> <span class="n">object_name</span><span class="p">[</span><span class="nb">len</span><span class="p">(</span><span class="n">app_config</span><span class="o">.</span><span class="n">name</span><span class="p">):]</span> <span class="k">if</span> <span class="n">subpath</span> <span class="o">==</span> <span class="s1">''</span> <span class="ow">or</span> <span class="n">subpath</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'.'</span><span class="p">:</span> <span class="n">candidates</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">app_config</span><span class="p">)</span> <span class="k">if</span> <span class="n">candidates</span><span class="p">:</span> <span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">candidates</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">ac</span><span class="p">:</span> <span class="o">-</span><span class="nb">len</span><span class="p">(</span><span class="n">ac</span><span class="o">.</span><span class="n">name</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span> <span class="k">def</span> <span class="nf">get_registered_model</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app_label</span><span class="p">,</span> <span class="n">model_name</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Similar to get_model(), but doesn't require that an app exists with</span> <span class="sd"> the given app_label.</span> <span class="sd"> It's safe to call this method at import time, even while the registry</span> <span class="sd"> is being populated.</span> <span class="sd"> """</span> <span class="n">model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_models</span><span class="p">[</span><span class="n">app_label</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">model_name</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span> <span class="k">if</span> <span class="n">model</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="k">raise</span> <span class="ne">LookupError</span><span class="p">(</span> <span class="s2">"Model '</span><span class="si">%s</span><span class="s2">.</span><span class="si">%s</span><span class="s2">' not registered."</span> <span class="o">%</span> <span class="p">(</span><span class="n">app_label</span><span class="p">,</span> <span class="n">model_name</span><span class="p">))</span> <span class="k">return</span> <span class="n">model</span> <span class="k">def</span> <span class="nf">set_available_apps</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">available</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Restricts the set of installed apps used by get_app_config[s].</span> <span class="sd"> available must be an iterable of application names.</span> <span class="sd"> set_available_apps() must be balanced with unset_available_apps().</span> <span class="sd"> Primarily used for performance optimization in TransactionTestCase.</span> <span class="sd"> This method is safe is the sense that it doesn't trigger any imports.</span> <span class="sd"> """</span> <span class="n">available</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">available</span><span class="p">)</span> <span class="n">installed</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">app_config</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">app_config</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_app_configs</span><span class="p">())</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">available</span><span class="o">.</span><span class="n">issubset</span><span class="p">(</span><span class="n">installed</span><span class="p">):</span> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"Available apps isn't a subset of installed "</span> <span class="s2">"apps, extra apps: </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">available</span> <span class="o">-</span> <span class="n">installed</span><span class="p">))</span> <span class="bp">self</span><span class="o">.</span><span class="n">stored_app_configs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="p">(</span> <span class="p">(</span><span class="n">label</span><span class="p">,</span> <span class="n">app_config</span><span class="p">)</span> <span class="k">for</span> <span class="n">label</span><span class="p">,</span> <span class="n">app_config</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">if</span> <span class="n">app_config</span><span class="o">.</span><span class="n">name</span> <span class="ow">in</span> <span class="n">available</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">clear_cache</span><span class="p">()</span> <span class="k">def</span> <span class="nf">unset_available_apps</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Cancels a previous call to set_available_apps().</span> <span class="sd"> """</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">stored_app_configs</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">clear_cache</span><span class="p">()</span> <span class="k">def</span> <span class="nf">set_installed_apps</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">installed</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Enables a different set of installed apps for get_app_config[s].</span> <span class="sd"> installed must be an iterable in the same format as INSTALLED_APPS.</span> <span class="sd"> set_installed_apps() must be balanced with unset_installed_apps(),</span> <span class="sd"> even if it exits with an exception.</span> <span class="sd"> Primarily used as a receiver of the setting_changed signal in tests.</span> <span class="sd"> This method may trigger new imports, which may add new models to the</span> <span class="sd"> registry of all imported models. They will stay in the registry even</span> <span class="sd"> after unset_installed_apps(). Since it isn't possible to replay</span> <span class="sd"> imports safely (eg. that could lead to registering listeners twice),</span> <span class="sd"> models are registered when they're imported and never removed.</span> <span class="sd"> """</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">ready</span><span class="p">:</span> <span class="k">raise</span> <span class="n">AppRegistryNotReady</span><span class="p">(</span><span class="s2">"App registry isn't ready yet."</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">stored_app_configs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">apps_ready</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">models_ready</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ready</span> <span class="o">=</span> <span class="kc">False</span> <span class="bp">self</span><span class="o">.</span><span class="n">clear_cache</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">populate</span><span class="p">(</span><span class="n">installed</span><span class="p">)</span> <span class="k">def</span> <span class="nf">unset_installed_apps</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Cancels a previous call to set_installed_apps().</span> <span class="sd"> """</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">stored_app_configs</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">apps_ready</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">models_ready</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ready</span> <span class="o">=</span> <span class="kc">True</span> <span class="bp">self</span><span class="o">.</span><span class="n">clear_cache</span><span class="p">()</span> <span class="k">def</span> <span class="nf">clear_cache</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Clears all internal caches, for methods that alter the app registry.</span> <span class="sd"> This is mostly used in tests.</span> <span class="sd"> """</span> <span class="c1"># Call expire cache on each model. This will purge</span> <span class="c1"># the relation tree and the fields cache.</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_models</span><span class="o">.</span><span class="n">cache_clear</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">ready</span><span class="p">:</span> <span class="k">for</span> <span class="n">model</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_models</span><span class="p">(</span><span class="n">include_auto_created</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span> <span class="n">model</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">_expire_cache</span><span class="p">()</span> <span class="c1"># ### DEPRECATED METHODS GO BELOW THIS LINE ###</span> <span class="k">def</span> <span class="nf">load_app</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app_name</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Loads the app with the provided fully qualified name, and returns the</span> <span class="sd"> model module.</span> <span class="sd"> """</span> <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span> <span class="s2">"load_app(app_name) is deprecated."</span><span class="p">,</span> <span class="n">RemovedInDjango19Warning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="n">app_config</span> <span class="o">=</span> <span class="n">AppConfig</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">app_name</span><span class="p">)</span> <span class="n">app_config</span><span class="o">.</span><span class="n">import_models</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">all_models</span><span class="p">[</span><span class="n">app_config</span><span class="o">.</span><span class="n">label</span><span class="p">])</span> <span class="bp">self</span><span class="o">.</span><span class="n">app_configs</span><span class="p">[</span><span class="n">app_config</span><span class="o">.</span><span class="n">label</span><span class="p">]</span> <span class="o">=</span> <span class="n">app_config</span> <span class="bp">self</span><span class="o">.</span><span class="n">clear_cache</span><span class="p">()</span> <span class="k">return</span> <span class="n">app_config</span><span class="o">.</span><span class="n">models_module</span> <span class="k">def</span> <span class="nf">app_cache_ready</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span> <span class="s2">"app_cache_ready() is deprecated in favor of the ready property."</span><span class="p">,</span> <span class="n">RemovedInDjango19Warning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">ready</span> <span class="k">def</span> <span class="nf">get_app</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app_label</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Returns the module containing the models for the given app_label.</span> <span class="sd"> """</span> <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span> <span class="s2">"get_app_config(app_label).models_module supersedes get_app(app_label)."</span><span class="p">,</span> <span class="n">RemovedInDjango19Warning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="n">models_module</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_app_config</span><span class="p">(</span><span class="n">app_label</span><span class="p">)</span><span class="o">.</span><span class="n">models_module</span> <span class="k">except</span> <span class="ne">LookupError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span> <span class="c1"># Change the exception type for backwards compatibility.</span> <span class="k">raise</span> <span class="n">ImproperlyConfigured</span><span class="p">(</span><span class="o">*</span><span class="n">exc</span><span class="o">.</span><span class="n">args</span><span class="p">)</span> <span class="k">if</span> <span class="n">models_module</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="k">raise</span> <span class="n">ImproperlyConfigured</span><span class="p">(</span> <span class="s2">"App '</span><span class="si">%s</span><span class="s2">' doesn't have a models module."</span> <span class="o">%</span> <span class="n">app_label</span><span class="p">)</span> <span class="k">return</span> <span class="n">models_module</span> <span class="k">def</span> <span class="nf">get_apps</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Returns a list of all installed modules that contain models.</span> <span class="sd"> """</span> <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span> <span class="s2">"[a.models_module for a in get_app_configs()] supersedes get_apps()."</span><span class="p">,</span> <span class="n">RemovedInDjango19Warning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="n">app_configs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_app_configs</span><span class="p">()</span> <span class="k">return</span> <span class="p">[</span><span class="n">app_config</span><span class="o">.</span><span class="n">models_module</span> <span class="k">for</span> <span class="n">app_config</span> <span class="ow">in</span> <span class="n">app_configs</span> <span class="k">if</span> <span class="n">app_config</span><span class="o">.</span><span class="n">models_module</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">]</span> <span class="k">def</span> <span class="nf">_get_app_package</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app</span><span class="p">):</span> <span class="k">return</span> <span class="s1">'.'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">__name__</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span> <span class="k">def</span> <span class="nf">get_app_package</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app_label</span><span class="p">):</span> <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span> <span class="s2">"get_app_config(label).name supersedes get_app_package(label)."</span><span class="p">,</span> <span class="n">RemovedInDjango19Warning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_app_package</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_app</span><span class="p">(</span><span class="n">app_label</span><span class="p">))</span> <span class="k">def</span> <span class="nf">_get_app_path</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app</span><span class="p">):</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="s1">'__path__'</span><span class="p">):</span> <span class="c1"># models/__init__.py package</span> <span class="n">app_path</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">__path__</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">else</span><span class="p">:</span> <span class="c1"># models.py module</span> <span class="n">app_path</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">__file__</span> <span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">upath</span><span class="p">(</span><span class="n">app_path</span><span class="p">))</span> <span class="k">def</span> <span class="nf">get_app_path</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app_label</span><span class="p">):</span> <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span> <span class="s2">"get_app_config(label).path supersedes get_app_path(label)."</span><span class="p">,</span> <span class="n">RemovedInDjango19Warning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_app_path</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_app</span><span class="p">(</span><span class="n">app_label</span><span class="p">))</span> <span class="k">def</span> <span class="nf">get_app_paths</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Returns a list of paths to all installed apps.</span> <span class="sd"> Useful for discovering files at conventional locations inside apps</span> <span class="sd"> (static files, templates, etc.)</span> <span class="sd"> """</span> <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span> <span class="s2">"[a.path for a in get_app_configs()] supersedes get_app_paths()."</span><span class="p">,</span> <span class="n">RemovedInDjango19Warning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_apps_ready</span><span class="p">()</span> <span class="n">app_paths</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">app</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_apps</span><span class="p">():</span> <span class="n">app_paths</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_get_app_path</span><span class="p">(</span><span class="n">app</span><span class="p">))</span> <span class="k">return</span> <span class="n">app_paths</span> <span class="k">def</span> <span class="nf">register_models</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app_label</span><span class="p">,</span> <span class="o">*</span><span class="n">models</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Register a set of models as belonging to an app.</span> <span class="sd"> """</span> <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span> <span class="s2">"register_models(app_label, *models) is deprecated."</span><span class="p">,</span> <span class="n">RemovedInDjango19Warning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> <span class="k">for</span> <span class="n">model</span> <span class="ow">in</span> <span class="n">models</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">register_model</span><span class="p">(</span><span class="n">app_label</span><span class="p">,</span> <span class="n">model</span><span class="p">)</span> <span class="n">apps</span> <span class="o">=</span> <span class="n">Apps</span><span class="p">(</span><span class="n">installed_apps</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span> </pre></div> </div> </div> </div> <div class="yui-b" id="sidebar"> <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> <div class="sphinxsidebarwrapper"> <h3>Browse</h3> <ul> </ul> <h3>You are here:</h3> <ul> <li> <a href="../../../index.html">Django 1.8.19 documentation</a> <ul><li><a href="../../index.html">Module code</a> <ul><li><a href="../../django.html">django</a> <ul><li>django.apps.registry</li></ul> </li></ul></li></ul> </li> </ul> <div id="searchbox" style="display: none" role="search"> <h3>Quick search</h3> <form class="search" action="../../../search.html" method="get"> <div><input type="text" name="q" /></div> <div><input type="submit" value="Go" /></div> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <h3>Last update:</h3> <p class="topless">Feb 12, 2019</p> </div> </div> <div id="ft"> <div class="nav"> <a href="../../index.html" title="Module code" accesskey="U">up</a></div> </div> </div> <div class="clearer"></div> </div> </body> </html>