使用 Django,有没有更好的方法在 urls.py 中动态导入视图?

Posted

技术标签:

【中文标题】使用 Django,有没有更好的方法在 urls.py 中动态导入视图?【英文标题】:With Django, is there a better way to dynamically import views in urls.py? 【发布时间】:2011-04-14 11:16:29 【问题描述】:

总结:

假设我在 Django 中有一个名为“devsite”的项目,它将首先部署到临时项目(也称为“devsite”),最后部署到实时代码库(该项目称为“livesite”)。在实时部署期间,我必须对 urls.py 进行手动更改,以便从正确的项目中导入视图。这意味着“devsite”中的 urls.py 将使用类似:

from devsite import views

“livesite”的 urls.py 将更改为:

from livesite import views

我的解决方案:

以下似乎有效(到目前为止测试有限)。我所做的是在 settings.py 中创建一个变量以从目录中获取项目名称,如下所示:

settings.py

# /settings.py
import os.path
PROJECT_NAME = os.path.basename(os.path.dirname(__file__))

然后用这个在urls.py中导入正确的视图:

urls.py

# /urls.py
from django.conf import settings
website = __import__('%s' % settings.PROJECT_NAME, fromlist=['views'])
...
urlpatterns = patterns('',
    (r'^monty/$', website.views.monty),
)

我的问题:

我想知道的是:

    这是做我想做的事的好方法,还是有更好的编码方法? 或者我是否需要重新考虑我的整个部署工作流程?

提前致谢。

【问题讨论】:

【参考方案1】:

看看 zc.buildout 和 djangorecipe - 正如 Jacob Kaplan-Moss 所说,

...is an exceedingly civilized way to develop an app

http://jacobian.org/writing/django-apps-with-buildout/

除了一般的“文明”之外,djangorecipe 允许您拥有多个设置文件,这些设置文件可以相互导入。然后您可以指定在特定安装中使用哪个设置文件。

开发.py

from settings import *
DEBUG = True

live.py

from settings import *
DEBUG = False

...这只是冰山一角

【讨论】:

这看起来不错。我会在未来的项目中记住这一点,尽管现在对于我正在处理的简单项目来说可能有点过头了。【参考方案2】:

我会质疑为什么您的实时网站和开发网站有不同的项目。为什么不将所有差异都归结为设置/配置(例如,您对PROJECT_NAME 所做的),而是让您的项目保持通用?看起来你只会增加开发和生活之间的任何错误机会,因为你使每个站点不同。

除此之外,我认为您正在做的事情或多或少都很好。我见过的另一种模式是这样的:

try:
    from livesite import views
except ImportError:
    from devsite import views

【讨论】:

在我的本地机器上,源仅作为 devsite 项目存在。它仅在我首先将 devsite 代码部署到登台项目中的远程主机上,然后将其部署到 livesite 项目中。我当时的逻辑是,我可以从同一个 Django 安装中同时提供这两种服务。但是我现在看到了该设置的缺陷;例如,当需要升级 Django 时。我见过你提到的“尝试除外”模式,但我不希望解决方案与项目名称耦合,以防我更改名称。我将使用一个项目名称。谢谢你让我重新思考。

以上是关于使用 Django,有没有更好的方法在 urls.py 中动态导入视图?的主要内容,如果未能解决你的问题,请参考以下文章

Django 将变量传递给 URL 标签

Django - 模板中多个 if 的更好方法

更好的方法从 django 的数据库中检索最近的 10 个项目

Django 在视图之间传递数据

如何在 django 中的所有 url 使用 slug 之前或之后没有任何内容?

在 C# 中验证 URL 比 try-catch 更好的方法?