Skip to content
Browse files

Added get_app_paths() to the AppCache.

This method is useful to discover files inside apps.
  • Loading branch information...
1 parent 09d0568 commit b55624a0263e31be80fbe7bb51e47ccd253e7a5d @aaugustin aaugustin committed
Showing with 22 additions and 2 deletions.
  1. +1 −1 django/db/models/
  2. +21 −1 django/db/models/
2 django/db/models/
@@ -1,7 +1,7 @@
from functools import wraps
from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured
-from django.db.models.loading import get_apps, get_app, get_models, get_model, register_models
+from django.db.models.loading import get_apps, get_app_paths, get_app, get_models, get_model, register_models
from django.db.models.query import Q
from django.db.models.expressions import F
from django.db.models.manager import Manager
22 django/db/models/
@@ -130,7 +130,9 @@ def app_cache_ready(self):
return self.loaded
def get_apps(self):
- "Returns a list of all installed modules that contain models."
+ """
+ Returns a list of all installed modules that contain models.
+ """
# Ensure the returned list is always in the same order (with new apps
@@ -140,6 +142,23 @@ def get_apps(self):
return [elt[1] for elt in apps]
+ def get_app_paths(self):
@timgraham Django member

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.


@aaugustin Django member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ """
+ Returns a list of paths to all installed apps.
+ Useful for discovering files at conventional locations inside apps
+ (static files, templates, etc.)
+ """
+ self._populate()
+ app_paths = []
+ for app in self.get_apps():
+ if hasattr(app, '__path__'): # models/ package
+ app_paths.extend([upath(path) for path in app.__path__])
@timgraham Django member

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.

@aaugustin Django member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ else: # module
+ app_paths.append(upath(app.__file__))
+ return app_paths
def get_app(self, app_label, emptyOK=False):
Returns the module containing the models for the given app_label. If
@@ -260,6 +279,7 @@ def register_models(self, app_label, *models):
# These methods were always module level, so are kept that way for backwards
# compatibility.
get_apps = cache.get_apps
+get_app_paths = cache.get_app_paths
get_app = cache.get_app
get_app_errors = cache.get_app_errors
get_models = cache.get_models

0 comments on commit b55624a

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