如何通过sys.modules hack将变量转换为模块?

时间:2019-06-04 22:07:19

标签: django django-models django-migrations

import os
from glob import glob
from importlib import import_module

from django.urls import re_path as _re_path, path as _path


def _glob_init(name):
    name = name.replace('.', os.sep)
    path = os.sep + '**'
    modules = []
    for module in glob(name + path, recursive=True):
        importable = os.path.splitext(module)[0].replace(os.sep, '.')
        if '__' in importable:
            continue
        try:
            module = import_module(importable)
        except ModuleNotFoundError:
            module = import_module(importable[:-1])
        modules.append(module)
    return modules


class UrlManager:
    def __init__(self, views_root):
        self.views_root = views_root
        self._url_patterns = []

    def _path(self, route, kwargs=None, name=None, is_re=None):
        func = _re_path if is_re else _path

        def decorator(view):
            _view = view  # keep the original view
            if isinstance(view, type):
                view = view.as_view()
            self._url_patterns.append(
                func(route, view, kwargs=kwargs, name=name or view.__name__)
            )
            return _view

        return decorator

    def path(self, route, kwargs=None, name=None):
        return self._path(route, kwargs=kwargs, name=name, is_re=False)

    def re_path(self, route, kwargs=None, name=None):
        return self._path(route, kwargs=kwargs, name=name, is_re=True)

    @property
    def url_patterns(self):
        if isinstance(self.views_root, str):
            _glob_init(self.views_root)
        else:
            for root in self.views_root:
                _glob_init(root)
        return self._url_patterns

基本用法:

# app.urls.py 

app_urls = UrlManager('app.views')

# app.views.py

from models import SomeModel
from urls import app_urls

@app_urls.path('foo/', name='foo')
def view(request):
    return response

# project.urls.py

from django.urls import include
from app.urls import app_urls

urlpatterns = [
    path('', include(app_urls.urlpatterns))
]

好的,现在:

当您已经启动并运行了迁移,但是要创建新的迁移时,一切都会正常进行。由于该代码流类似于:

-项目urls.py导入app.urls

-app.urls导入视图

-查看导入模型

-模型尚不存在,因为这是运行迁移命令

-错误

我需要以某种方式创建一个名为实例的模块,以便可以使用include('module.urls')或其他某种方式来推迟导入。

如果有人要打开公关,回购处位于https://github.com/isik-kaplan/django_urls

0 个答案:

没有答案
相关问题