Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added get_app_paths() to the AppCache.

This method is useful to discover files inside apps.
  • Loading branch information...
commit b55624a0263e31be80fbe7bb51e47ccd253e7a5d 1 parent 09d0568
Aymeric Augustin authored June 02, 2013
2  django/db/models/__init__.py
... ...
@@ -1,7 +1,7 @@
1 1
 from functools import wraps
2 2
 
3 3
 from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured
4  
-from django.db.models.loading import get_apps, get_app, get_models, get_model, register_models
  4
+from django.db.models.loading import get_apps, get_app_paths, get_app, get_models, get_model, register_models
5 5
 from django.db.models.query import Q
6 6
 from django.db.models.expressions import F
7 7
 from django.db.models.manager import Manager
22  django/db/models/loading.py
@@ -130,7 +130,9 @@ def app_cache_ready(self):
130 130
         return self.loaded
131 131
 
132 132
     def get_apps(self):
133  
-        "Returns a list of all installed modules that contain models."
  133
+        """
  134
+        Returns a list of all installed modules that contain models.
  135
+        """
134 136
         self._populate()
135 137
 
136 138
         # Ensure the returned list is always in the same order (with new apps
@@ -140,6 +142,23 @@ def get_apps(self):
140 142
         apps.sort()
141 143
         return [elt[1] for elt in apps]
142 144
 
  145
+    def get_app_paths(self):
  146
+        """
  147
+        Returns a list of paths to all installed apps.
  148
+
  149
+        Useful for discovering files at conventional locations inside apps
  150
+        (static files, templates, etc.)
  151
+        """
  152
+        self._populate()
  153
+
  154
+        app_paths = []
  155
+        for app in self.get_apps():
  156
+            if hasattr(app, '__path__'):        # models/__init__.py package
  157
+                app_paths.extend([upath(path) for path in app.__path__])
  158
+            else:                               # models.py module
  159
+                app_paths.append(upath(app.__file__))
  160
+        return app_paths
  161
+
143 162
     def get_app(self, app_label, emptyOK=False):
144 163
         """
145 164
         Returns the module containing the models for the given app_label. If
@@ -260,6 +279,7 @@ def register_models(self, app_label, *models):
260 279
 # These methods were always module level, so are kept that way for backwards
261 280
 # compatibility.
262 281
 get_apps = cache.get_apps
  282
+get_app_paths = cache.get_app_paths
263 283
 get_app = cache.get_app
264 284
 get_app_errors = cache.get_app_errors
265 285
 get_models = cache.get_models

0 notes on commit b55624a

Tim Graham

This is a little confusing to me in that the paths it returns contain models.pyc or end with "/models"

I propose modifying it to return just the app paths so that callers don't have to call or.path.dirname on each path that's returned. Let me know if I'm missing something.

#1359

Tim Graham

will app.path ever be a list of length > 1? I changed this to app.path[0] in the pull request referenced in the above comment - again, let me know if I'm missing something.

Aymeric Augustin

Please do.

This method is less useful than I originally envisioned because it returns a list based on the app cache, while most discoveries are based on INSTALLED_APPS, which may be a subset of the applications registered in the app cache.

Aymeric Augustin

I didn't write that code, merely moved it. If __path__ is a list I assume it could contain more than one element but I don't know under which circumstances that could happen.

Please sign in to comment.
Something went wrong with that request. Please try again.