Подкаталог Django просматривает и импортирует все файлы из __init__.py - PullRequest
2 голосов
/ 28 октября 2010

Технически это не вопрос django, а скорее вопрос по питону.

В 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.1018 * Используемая версия кода Амита:

. Это в файле 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 Ответ

1 голос
/ 24 августа 2011

Я считаю, что импортировать через другие файлы несколько неудобно, и что все представления должны импортироваться напрямую - как вы делаете сейчас. Тем не менее, вы можете создать файл views.py и импортировать оттуда все соответствующие методы view, структура dir останется прежней, только вы добавите файл views.py в views / dir. Код в самом файле должен выглядеть примерно так:

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...