在 Django 项目中加载特定 url(视图)的最佳方法
Best approach to load specific urls (views) in Django project
我有一个公开以下视图的 Django 应用程序:A,B,C...Z
。此应用部署在 MACHINE-1 上。
有一个新的业务需求,即在 MACHINE-2 上部署相同的 Django 应用程序,但使用这些视图的子集,比方说 A,B, C
。
我的简单解决方案是设置一个配置变量(RUN_ON_MACHINE_2=True
用于第二种情况,False
用于第一种情况)。总之,urls.py
文件如下所示(请注意,我在这里将视图与路径同化只是为了使其更短):
urlpatterns = [A, B, C, ... Z]
# If the env var is set to True then only load a subset of the views
if config.RUN_ON_MACHINE_2:
urlpatterns = [A, B, C]
测试工作正常,因为它们总是为 A,B,C ... Z
执行,当然包括 A, B, C
.
但是,一些新的业务需求要求对视图 A 进行更改。我可以通过 config.RUN_ON_MACHINE_2
变量分支代码来实现视图 A 中的更改,但我得出的结论是创建一个更清晰的视图新视图 A_ForMachine2
,它仅实现 MACHINE_2 所需的内容。 A_ForMachine2
必须与视图 A
具有相同的界面,并且必须挂载到相同的路径。所以新的 urls.py
看起来像:
urlpatterns = [A, B, C, ... Z]
# If the env var is set to True then only load a subset of the views
if config.RUN_ON_MACHINE_2:
# A_ForMachine2 is mounted on the same path as A
urlpatterns = [A_ForMachine2, B, C]
现在我有 2 个视图挂载到同一路径,因此它们具有相同的 URL。
现在我的 api 测试只测试视图 A
因为默认情况下 config.RUN_ON_MACHINE_2
是 False。
我试图在我的测试用例中修补 config.RUN_ON_MACHINE_2
但据我了解,当测试 运行 时应用程序已经加载了所有 url A,B,..Z
所以它不会load/mount [A_ForMachine2, B, C]
.
让 Django 应用程序(在我的例子中是 DRF 应用程序)在启动时加载不同的 url(取决于某些环境变量)并使其所有视图都易于测试的干净方法是什么?
干杯!
ROOT_URLCONF 救援
首先,永远不要为不同的机器环境使用这种 if-else 架构。
始终在 .env 文件中添加 SETTINGS
变量并创建不同的设置文件,例如 dev
、qa
、stage
、prod
或 local
。在您的情况下,为 Machine-1
和 Machine-2
.
创建不同的设置文件
然后在您的设置中根据您对不同环境的需要 url 更新 ROOT_URLCONF
。
您的主 urls.py
将转换为 urls
文件夹,您可以在其中添加名为 urls 的计算机。然后在各自的设置中添加ROOT_URLCONF
的路径。
您的 urls
结构如下所示:
urls
├── __init__.py
├── common.py
├── local.py
└── production.py
您的不同设置文件将具有如下属性:
# settings/local.py
ROOT_URLCONF = 'urls.local'
还有这个
# settings/production.py
ROOT_URLCONF = 'urls.production'
主要变化将发生在 urlspattern
:
# urls/local.py
from .common.py import urlpatterns as common_urlpatterns
urlpatterns = common_urlpatterns + [
url(r'^A-view-path/', include(app_1.urls_for_A)),
]
您可以使用不同的名称使两个视图的功能略有不同。但是将相同的 url 添加到具有一个视图的机器一和具有另一个视图的机器二。
这里有一个类似的。我从这里复制了一些关于文件夹结构的参考。我遇到了同样的问题,因为我只需要在测试和本地实例上进行代码分析 urls,而不是在 dev、qa 和 prod 实例上。那么这个帮助很大。
如果您现在添加 if-else 架构,那么您将来会遇到可伸缩性问题。如果你离开了公司,其他新开发人员大部分时间都会挠头,因为没人知道为什么会这样。
不要忘记添加评论,让其他人知道您的确切意图。
我有一个公开以下视图的 Django 应用程序:A,B,C...Z
。此应用部署在 MACHINE-1 上。
有一个新的业务需求,即在 MACHINE-2 上部署相同的 Django 应用程序,但使用这些视图的子集,比方说 A,B, C
。
我的简单解决方案是设置一个配置变量(RUN_ON_MACHINE_2=True
用于第二种情况,False
用于第一种情况)。总之,urls.py
文件如下所示(请注意,我在这里将视图与路径同化只是为了使其更短):
urlpatterns = [A, B, C, ... Z]
# If the env var is set to True then only load a subset of the views
if config.RUN_ON_MACHINE_2:
urlpatterns = [A, B, C]
测试工作正常,因为它们总是为 A,B,C ... Z
执行,当然包括 A, B, C
.
但是,一些新的业务需求要求对视图 A 进行更改。我可以通过 config.RUN_ON_MACHINE_2
变量分支代码来实现视图 A 中的更改,但我得出的结论是创建一个更清晰的视图新视图 A_ForMachine2
,它仅实现 MACHINE_2 所需的内容。 A_ForMachine2
必须与视图 A
具有相同的界面,并且必须挂载到相同的路径。所以新的 urls.py
看起来像:
urlpatterns = [A, B, C, ... Z]
# If the env var is set to True then only load a subset of the views
if config.RUN_ON_MACHINE_2:
# A_ForMachine2 is mounted on the same path as A
urlpatterns = [A_ForMachine2, B, C]
现在我有 2 个视图挂载到同一路径,因此它们具有相同的 URL。
现在我的 api 测试只测试视图 A
因为默认情况下 config.RUN_ON_MACHINE_2
是 False。
我试图在我的测试用例中修补 config.RUN_ON_MACHINE_2
但据我了解,当测试 运行 时应用程序已经加载了所有 url A,B,..Z
所以它不会load/mount [A_ForMachine2, B, C]
.
让 Django 应用程序(在我的例子中是 DRF 应用程序)在启动时加载不同的 url(取决于某些环境变量)并使其所有视图都易于测试的干净方法是什么?
干杯!
ROOT_URLCONF 救援
首先,永远不要为不同的机器环境使用这种 if-else 架构。
始终在 .env 文件中添加 SETTINGS
变量并创建不同的设置文件,例如 dev
、qa
、stage
、prod
或 local
。在您的情况下,为 Machine-1
和 Machine-2
.
然后在您的设置中根据您对不同环境的需要 url 更新 ROOT_URLCONF
。
您的主 urls.py
将转换为 urls
文件夹,您可以在其中添加名为 urls 的计算机。然后在各自的设置中添加ROOT_URLCONF
的路径。
您的 urls
结构如下所示:
urls
├── __init__.py
├── common.py
├── local.py
└── production.py
您的不同设置文件将具有如下属性:
# settings/local.py
ROOT_URLCONF = 'urls.local'
还有这个
# settings/production.py
ROOT_URLCONF = 'urls.production'
主要变化将发生在 urlspattern
:
# urls/local.py
from .common.py import urlpatterns as common_urlpatterns
urlpatterns = common_urlpatterns + [
url(r'^A-view-path/', include(app_1.urls_for_A)),
]
您可以使用不同的名称使两个视图的功能略有不同。但是将相同的 url 添加到具有一个视图的机器一和具有另一个视图的机器二。
这里有一个类似的
如果您现在添加 if-else 架构,那么您将来会遇到可伸缩性问题。如果你离开了公司,其他新开发人员大部分时间都会挠头,因为没人知道为什么会这样。
不要忘记添加评论,让其他人知道您的确切意图。