开发者

Django sub-directory views and import all files from __init__.py

Technically not a django question, more a python question.

In urls.py I've got the following:

urlpatterns = patterns('locate.views',
    url(r'^',  'index.index'),
)

And a directory structure like this:

locate/
  views/
    __init__.py
    index.py      #  where there is "def index(request) : ...."

What I would like to do is avoid having to say "index.index", but rather have things flatten out a bit. Thus yielding:

urlpatterns = patterns('locate.views',
    url(r'^',  'index'),
)

This of course is quite possible if I make __ init __.py contain:

from .index import index
...

But after the 99th time of doing that it would be nice to have it automated. I've gotten close with some poking around with __ import __ and the like but wondering if anybody else has a working code fragment and/or a better way to handle this pattern in django.

Update Used version of Amit's code:

this is in the views/__init__.py file (which will be pulled to a library shortly):

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__("%开发者_如何学Gos.%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__))


I believe that importing through other files is somewhat awkward, and that all views should be imported directly - like the way you're doing now. However, you can create a views.py file and import all relevant view methods from there, the dir structure will remain the same, only you'll add a views.py file under the views/ dir. The code in the file itself should be something like:

from .index import index
from .other_view import other_view_method
...

then the code in your urls.py file:

 urlpatterns = patterns('locate.views',
    url(r'^',  'index.index'), )

will turn into:

urlpatterns = patterns('locate.views.views',
    url(r'^',  'index'),
)

However, if you still want to run over all your *.py files and get all view methods from them, you can create a loader file that runs first and loads all views, the code should be something as follows:

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

Then in urls.py you add:

import_views()
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜