django-staticfiles-finder
8707 ワード
BaseFinderはすべてのFinderのベースクラスです.
BaseFinderは2つのメソッドfindとlistを定義した.
サブクラスFileSystemFinderはsettingsを実現する.STATICFILES_DIRSの探求.
FileSystemFinderクラスの初期化方法_init__,主にselfを初期化する.locationsとself.storagesの2つのプロパティ.
self.locationsのフォーマットは
self.storagesのフォーマットは
findメソッドは、ファイルの場所を探します.
findはselfをループするだけだ.locations、find_を呼び出しますlocationメソッドはdirごとに探します.
find_locationは、指定されたrootディレクトリの下で、pathというファイル名のファイルの場所を探す責任を負います.
Listは、ファイルのリストを表示します.
get_を呼び出すfilesはpathリストを取得します.
storageオブジェクトを使用してファイルのリストを取得し、ignore_を介して結果を表示します.patternsフィルタリングし、フィルタリングされたファイルを返します.
AppDirectoriesFinderは、各appの下にあるstaticファイルの検索を担当します.
self.appsのフォーマットは次のとおりです.
self.storagesのフォーマットは次のとおりです.
appsモジュールのget_を呼び出すapp_configs関数、app_を取得config.
次にselfを更新する.appsとself.storages
findメソッドはselfを循環する.apps、find_を呼び出すin_appメソッドは、appで検索することを指定します.
実質的には,対応するstorageのexistsメソッドを呼び出し,存在するか否かを判断する.
FileSystemFinderとAppDirectoriesFinderもFileSystemStorageを使用しており、各ディレクトリに対応するstorageがあります.
違うのはFileSystemFinderがosを通過することです.path.existはファイルが存在するかどうかを判断し、AppDirectoriesFinderはstorageを通過する.existが判断した.
class BaseFinder(object):
"""
A base file finder to be used for custom staticfiles finder classes.
"""
def find(self, path, all=False):
"""
Given a relative file path this ought to find an
absolute file path.
If the ``all`` parameter is ``False`` (default) only
the first found file path will be returned; if set
to ``True`` a list of all found files paths is returned.
"""
raise NotImplementedError('subclasses of BaseFinder must provide a find() method')
def list(self, ignore_patterns):
"""
Given an optional list of paths to ignore, this should return
a two item iterable consisting of the relative path and storage
instance.
"""
raise NotImplementedError('subclasses of BaseFinder must provide a list() method')
BaseFinderは2つのメソッドfindとlistを定義した.
サブクラスFileSystemFinderはsettingsを実現する.STATICFILES_DIRSの探求.
class FileSystemFinder(BaseFinder):
"""
A static files finder that uses the ``STATICFILES_DIRS`` setting
to locate files.
"""
def __init__(self, app_names=None, *args, **kwargs):
# List of locations with static files
self.locations = []
# Maps dir paths to an appropriate storage instance
self.storages = OrderedDict()
if not isinstance(settings.STATICFILES_DIRS, (list, tuple)):
raise ImproperlyConfigured(
"Your STATICFILES_DIRS setting is not a tuple or list; "
"perhaps you forgot a trailing comma?")
for root in settings.STATICFILES_DIRS:
if isinstance(root, (list, tuple)):
prefix, root = root
else:
prefix = ''
if settings.STATIC_ROOT and os.path.abspath(settings.STATIC_ROOT) == os.path.abspath(root):
raise ImproperlyConfigured(
"The STATICFILES_DIRS setting should "
"not contain the STATIC_ROOT setting")
if (prefix, root) not in self.locations:
self.locations.append((prefix, root))
for prefix, root in self.locations:
filesystem_storage = FileSystemStorage(location=root)
filesystem_storage.prefix = prefix
self.storages[root] = filesystem_storage
super(FileSystemFinder, self).__init__(*args, **kwargs)
FileSystemFinderクラスの初期化方法_init__,主にselfを初期化する.locationsとself.storagesの2つのプロパティ.
self.locationsのフォーマットは
[(prefix, dir), (prefix, dir), ...]
self.storagesのフォーマットは
{dir: FileSystemStorage, dir: FileSystemStorage, ...}
findメソッドは、ファイルの場所を探します.
findはselfをループするだけだ.locations、find_を呼び出しますlocationメソッドはdirごとに探します.
def find(self, path, all=False):
"""
Looks for files in the extra locations
as defined in ``STATICFILES_DIRS``.
"""
matches = []
for prefix, root in self.locations:
if root not in searched_locations:
searched_locations.append(root)
matched_path = self.find_location(root, path, prefix)
if matched_path:
if not all:
return matched_path
matches.append(matched_path)
return matches
find_locationは、指定されたrootディレクトリの下で、pathというファイル名のファイルの場所を探す責任を負います.
def find_location(self, root, path, prefix=None):
"""
Finds a requested static file in a location, returning the found
absolute path (or ``None`` if no match).
"""
if prefix:
prefix = '%s%s' % (prefix, os.sep)
if not path.startswith(prefix):
return None
path = path[len(prefix):]
path = safe_join(root, path)
if os.path.exists(path):
return path
Listは、ファイルのリストを表示します.
def list(self, ignore_patterns):
"""
List all files in all locations.
"""
for prefix, root in self.locations:
storage = self.storages[root]
for path in utils.get_files(storage, ignore_patterns):
yield path, storage
get_を呼び出すfilesはpathリストを取得します.
def get_files(storage, ignore_patterns=None, location=''):
"""
Recursively walk the storage directories yielding the paths
of all files that should be copied.
"""
if ignore_patterns is None:
ignore_patterns = []
directories, files = storage.listdir(location)
for fn in files:
if matches_patterns(fn, ignore_patterns):
continue
if location:
fn = os.path.join(location, fn)
yield fn
for dir in directories:
if matches_patterns(dir, ignore_patterns):
continue
if location:
dir = os.path.join(location, dir)
for fn in get_files(storage, ignore_patterns, dir):
yield fn
storageオブジェクトを使用してファイルのリストを取得し、ignore_を介して結果を表示します.patternsフィルタリングし、フィルタリングされたファイルを返します.
AppDirectoriesFinderは、各appの下にあるstaticファイルの検索を担当します.
class AppDirectoriesFinder(BaseFinder):
"""
A static files finder that looks in the directory of each app as
specified in the source_dir attribute.
"""
storage_class = FileSystemStorage
source_dir = 'static'
def __init__(self, app_names=None, *args, **kwargs):
# The list of apps that are handled
self.apps = []
# Mapping of app names to storage instances
self.storages = OrderedDict()
app_configs = apps.get_app_configs()
if app_names:
app_names = set(app_names)
app_configs = [ac for ac in app_configs if ac.name in app_names]
for app_config in app_configs:
app_storage = self.storage_class(os.path.join(app_config.path, self.source_dir))
if os.path.isdir(app_storage.location):
self.storages[app_config.name] = app_storage
if app_config.name not in self.apps:
self.apps.append(app_config.name)
super(AppDirectoriesFinder, self).__init__(*args, **kwargs)
self.appsのフォーマットは次のとおりです.
[app_name, app_name, ...]
self.storagesのフォーマットは次のとおりです.
{app_name: FileSystemStorage, app_name: FileSystemStorage, ...}
appsモジュールのget_を呼び出すapp_configs関数、app_を取得config.
次にselfを更新する.appsとself.storages
def find(self, path, all=False):
"""
Looks for files in the app directories.
"""
matches = []
for app in self.apps:
app_location = self.storages[app].location
if app_location not in searched_locations:
searched_locations.append(app_location)
match = self.find_in_app(app, path)
if match:
if not all:
return match
matches.append(match)
return matches
findメソッドはselfを循環する.apps、find_を呼び出すin_appメソッドは、appで検索することを指定します.
def find_in_app(self, app, path):
"""
Find a requested static file in an app's static locations.
"""
storage = self.storages.get(app, None)
if storage:
# only try to find a file if the source dir actually exists
if storage.exists(path):
matched_path = storage.path(path)
if matched_path:
return matched_path
実質的には,対応するstorageのexistsメソッドを呼び出し,存在するか否かを判断する.
def list(self, ignore_patterns):
"""
List all files in all app storages.
"""
for storage in six.itervalues(self.storages):
if storage.exists(''): # check if storage location exists
for path in utils.get_files(storage, ignore_patterns):
yield path, storage
FileSystemFinderとAppDirectoriesFinderもFileSystemStorageを使用しており、各ディレクトリに対応するstorageがあります.
違うのはFileSystemFinderがosを通過することです.path.existはファイルが存在するかどうかを判断し、AppDirectoriesFinderはstorageを通過する.existが判断した.