Django:动态添加应用作为插件,自动构建网址和其他设置 [英] Django: Dynamically add apps as plugin, building urls and other settings automatically

查看:16
本文介绍了Django:动态添加应用作为插件,自动构建网址和其他设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Django 中的文件夹结构如下:

./project_root./应用程序./夹具/./静止的/./模板/./博客/./settings.py./urls.py./views.py./manage.py./__init__.py./插入./code_editor./静止的./模板./urls.py./views.py./__init__.py./code_viewer./静止的./模板./urls.py./views.py./__init__.py

那么,如何通过基于 INSTALLED_APPS 查找其他 urls.py 使 root urls.py 自动构建 url 列表?我更改 settings.py 以动态构建 INSTALLED_APPS、TEMPLATES_DIR、STATICFILES_DIRS.(这意味着我不知道在不同的服务器上会安装多少个插件.它应该在运行时动态检查并添加它.)on:

python manage.py runserver

这是添加 INSTALLED_APPS、TEMPATES_DIR、STATICFILES_DIR 的代码.

PLUGINS_DIR = '/path_to/plugins/'对于 os.listdir(PLUGINS_DIR) 中的项目:如果 os.path.isdir(os.path.join(PLUGINS_DIR, item)):plugin_name = 'app.plugins.%s' % item如果 plugin_name 不在 INSTALLED_APPS 中:INSTALLED_APPS = INSTALLED_APPS+(plugin_name,)template_dir = os.path.join(PLUGINS_DIR, '%s/templates/' % item)如果 os.path.isdir(template_dir):如果 template_dir 不在 TEMPLATE_DIRS 中:TEMPLATE_DIRS = TEMPLATE_DIRS+(template_dir,)static_files_dir = os.path.join(PLUGINS_DIR, '%s/static/' % item)如果 os.path.isdir(static_files_dir):如果 static_files_dir 不在 STATICFILES_DIRS 中:STATICFILES_DIRS = STATICFILES_DIRS + (static_files_dir,)

任何帮助将不胜感激.提前致谢.

<块引用>

解决方案:

所以我所做的如下:

我包含两个这样的模块:

from django.conf 导入设置从 django.utils.importlib 导入 import_module

<块引用>

然后在根 urls.py 中添加以下代码:

def 美化(应用):返回 app.rsplit('.', 1)[1]对于 INSTALLED_APPS 中的应用程序:尝试:_module = import_module('%s.urls' % app)除了:经过别的:如果应用程序中的eats.plugins":urlpatterns += patterns('',url(r'^plugins/%s/' % prettify(app), include('%s.urls' % app)))

<块引用>

非常感谢@Yuka.谢谢你.谢谢你.谢谢你.谢谢....你让我开心.

解决方案

你想要的是这样的:

 from django.utils.importlib import import_module对于 settings.INSTALLED_APPS 中的应用程序:尝试:mod = import_module('%s.urls' % app)# 可能清理导入的模块之后?# 可能会弄乱`include(...)` 或留下污染的命名空间除了:# 模块导入后清理失败,# 也许你可以让 `include(...)` 报告失败经过别的:urlpatterns += patterns('',url(r'^%s/' % slugify(app), include('%s.urls' % app))

你还想从 django 模板或工具中窃取和实现你自己的 slugify(我现在不太确定它在哪里?)并稍微修改它以去除任何 '点"和其他您不想要的无用命名空间,例如在您的网址"中你可能不希望你的网址看起来像这样:'example.com/plugin.some_plugin_appname/' 但像 example.com/nice_looking_appname/

你甚至可能不想让它自动命名,而是在你的插件自己的设置"模块或类似的东西中做了一个可配置的设置":

#插件设置confurl_namespace = 'my_nice_plugin_url/'# 根 urls.py:url(r'^%s/' % mod.url_namespace, include(...))# 或者:url(r'^%s/' % app.settings.url_namespace, Inc..

你可能已经明白了要点.

亲切的问候,

I have following structure of my folders in Django:

./project_root
    ./app
       ./fixtures/
       ./static/
       ./templates/
       ./blog/
       ./settings.py
       ./urls.py
       ./views.py
       ./manage.py
       ./__init__.py 
    ./plugin
       ./code_editor
           ./static
           ./templates
           ./urls.py
           ./views.py
           ./__init__.py 
       ./code_viewer
           ./static
           ./templates
           ./urls.py
           ./views.py
           ./__init__.py 

So, how can I make root urls.py automatically build up the list of urls by looking for other urls.py based on the INSTALLED_APPS? I change settings.py in order to build INSTALLED_APPS, TEMPLATES_DIR, STATICFILES_DIRS dynamically. (It means i do not know how many plugins will be installed in different servers. It should dynamically check it on run time and add it.)on:

python manage.py runserver

Here is code for adding INSTALLED_APPS, TEMPATES_DIR, STATICFILES_DIR.

PLUGINS_DIR = '/path_to/plugins/'

for item in os.listdir(PLUGINS_DIR):
    if os.path.isdir(os.path.join(PLUGINS_DIR, item)):
        plugin_name = 'app.plugins.%s' % item

    if plugin_name not in INSTALLED_APPS:
        INSTALLED_APPS = INSTALLED_APPS+(plugin_name,)

    template_dir = os.path.join(PLUGINS_DIR, '%s/templates/' % item)

    if os.path.isdir(template_dir):
        if template_dir not in TEMPLATE_DIRS:
            TEMPLATE_DIRS = TEMPLATE_DIRS+(template_dir,)

    static_files_dir = os.path.join(PLUGINS_DIR, '%s/static/' % item)

    if os.path.isdir(static_files_dir):
        if static_files_dir not in STATICFILES_DIRS:
            STATICFILES_DIRS = STATICFILES_DIRS + (static_files_dir,)

Any help will be appreciated. Thank you in advance.

SOLUTION:

EDIT: So what i did are as following:

I include two modules like this:

from django.conf import settings
    from django.utils.importlib import import_module

And then in root urls.py I add following code:

def prettify(app):
    return app.rsplit('.', 1)[1]


for app in INSTALLED_APPS:

    try:
        _module = import_module('%s.urls' % app)
    except:
        pass
    else:
        if 'eats.plugins' in app:
            urlpatterns += patterns('',
                                    url(r'^plugins/%s/' % prettify(app), include('%s.urls' % app))
                                    )

Thank you a lot @Yuka. Thank you. Thank you. Thank you. Thank you.... You make my day.

解决方案

What you'll want is something like this:

from django.utils.importlib import import_module
for app in settings.INSTALLED_APPS:

    try:
        mod = import_module('%s.urls' % app)
        # possibly cleanup the after the imported module?
        #  might fuss up the `include(...)` or leave a polluted namespace
    except:
        # cleanup after module import if fails,
        #  maybe you can let the `include(...)` report failures
        pass
    else:
        urlpatterns += patterns('',
            url(r'^%s/' % slugify(app), include('%s.urls' % app)
        )

You'll also want to steal and implement your own slugify from django template or utils (I'm not exactly sure where it lives these days?) and slightly modify it to strip out any 'dots' and other useless namespacing you don't want in your 'url' e.g. you might not want your urls looking like so: 'example.com/plugin.some_plugin_appname/' but like example.com/nice_looking_appname/

You might even not want it automagicly named after all, and instead made a configurable 'setting' in your plugins own 'settings' module or something like so:

# plugin settings conf
url_namespace = 'my_nice_plugin_url/'

# root urls.py:
url(r'^%s/' % mod.url_namespace, include(...))
# or:
url(r'^%s/' % app.settings.url_namespace, inc..

You probably get the gist of it.

Kind regards,

这篇关于Django:动态添加应用作为插件,自动构建网址和其他设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆