Django子目录视图及从__init__.py导入所有文件
从技术上讲,这不是一个关于Django的问题,更像是一个关于Python的问题。
在urls.py文件里,我有以下内容:
urlpatterns = patterns('locate.views',
url(r'^', 'index.index'),
)
还有这样的目录结构:
locate/
views/
__init__.py
index.py # where there is "def index(request) : ...."
我想要做的是,不想每次都说“index.index”,而是希望能让结构简单一些。这样就能得到:
urlpatterns = patterns('locate.views',
url(r'^', 'index'),
)
当然,如果我在__ init __.py文件里写入以下内容,这是完全可以实现的:
from .index import index
...
但是在做了99次之后,能自动化这个过程就太好了。我尝试了一些__ import __之类的东西,已经接近了,但我想知道有没有其他人有可用的代码片段,或者有没有更好的方法来处理Django中的这种模式。
更新 使用了Amit代码的版本:
这段代码在views/__init__.py
文件里(很快会被拉到一个库里):
from glob import glob1
from types import FunctionType
import os
def import_views(dirname, views_prefix='') :
for filename in glob1(dirname, '*.py'):
if filename == '__init__.py': # I assume you don't want that
continue
module_name = os.path.basename(filename).split('.py')[0]
# You might need to change this, depending on where you run the file:
imported_module = __import__("%s.%s" % (__package__, module_name), fromlist=[module_name,])
idict = imported_module.__dict__
for method_name in idict.get('__all__', idict.keys()):
method = idict[method_name]
if not isinstance(method, FunctionType):
continue
if views_prefix and not method_name.startswith(views_prefix):
continue
globals()[method_name] = method
import_views(os.path.dirname(__file__))
1 个回答
2
我觉得通过其他文件导入有点麻烦,所有的视图应该直接导入,就像你现在做的那样。不过,你可以创建一个 views.py 文件,把所有相关的视图方法从那里导入,目录结构保持不变,只需要在 views/ 目录下添加一个 views.py 文件。这个文件里的代码应该像这样:
from .index import index
from .other_view import other_view_method
...
然后在你的 urls.py 文件中的代码会变成:
urlpatterns = patterns('locate.views',
url(r'^', 'index.index'), )
变成这样:
urlpatterns = patterns('locate.views.views',
url(r'^', 'index'),
)
不过,如果你还是想遍历所有的 *.py 文件并从中获取所有视图方法,你可以创建一个加载器文件,先运行这个文件来加载所有视图,代码应该像这样:
from glob import glob1
from types import FunctionType
VIEW_METHOD_PREFIX = '' # Whatever you like here, I suggest you use something
VIEWS_DIR = 'views' # Where you views are
def import_views():
for filename in glob1(VIEWS_DIR, '*.py'):
if filename == '__init__.py': # I assume you don't want that
continue
module_name = os.path.basename(filename).split('.py')[0]
# You might need to change this, depending on where you run the file:
imported_module = __import__(
module_name, fromlist=[module_name,])
for method_name, method in imported_module.__dict__.iteritems():
if not isinstance(method, FunctionType):
continue
if not method_name.startswith(VIEW_METHOD_PREFIX):
continue
globals()[method_name] = method
然后在 urls.py 中你添加:
import_views()