从任何地方为您的网站创建URL。
项目描述
Django URLconf 导出
您需要在另一个微服务中为Django网站创建URL吗?
这曾经是个痛苦的过程;您不得不在多个地方硬编码URL逻辑。
这很混乱且脆弱,尤其是当URL翻译为多种语言时。
但现在,Django URLconf 导出已解决了这个问题。
它以JSON格式导出您的网站URLconf,然后将其导入到任何其他Python服务中。
因此,您可以从任何地方轻松创建网站URL,没有任何麻烦、重复和债务。
一些示例用途
- 发送链接到用户的电子邮件微服务。
- 生成sitmaps的微服务。
- 为某些网站页面购买付费广告的微服务。
视频:7分钟概览
目录
用户指南
安装
该软件包名称为 django-urlconf-export
一些安装方法
pipenv install django-urlconf-export
pip install django-urlconf-export
poetry add django-urlconf-export
将URLconf导出为JSON
如果您有此URLconf
urlpatterns = [
url(r"^login/$", View.as_view(), name="login"),
]
您可以运行此代码
from django_urlconf_export import export_urlconf
export_urlconf.as_json()
您将得到此JSON
[
{"regex": "^login/$", "name": "login"},
]
然后在某个地方,您可以像这样导入JSON
from django_urlconf_export import import_urlconf
import_urlconf.from_json(json_urlpatterns)
然后您可以通过调用 reverse
来创建URL,就像平常一样
reverse("login") == "/login/"
将URLconf保存到文件
如果您将 django_urlconf_export
添加到您网站的 INSTALLED_APPS
中,您可以运行
django-admin export_urlconf_to_file > "urlconf.json"
创建一个名为 urlconf.json
的文件
然后您可以在其他地方像这样导入文件
import_urlconf.from_file("urlconf.json")
示例用例
在Lyst,我们有一个共享的骨架仓库,我们与为我们的网站创建特殊页面的数字机构共享,例如 2019年时尚年度。该仓库是我们生产环境的简化模拟。机构在仓库内为我们网站开发页面,因此集成变得容易。
我们在骨架仓库中包含一个URLconf文件。在我们这样做之前,机构通常会将URL硬编码到他们的工作中。但现在
- 他们可以以标准的Django方式创建URL。
- URL始终正确;没有静默错误。
- URL已经为所有我们支持的语言进行了本地化。
从端点提供URLconf
此视图返回URLconf JSON
from django_urlconf_export.views.export import URLConfExportView
urlpatterns = [
url(r"^urlconf/", URLConfExportView.as_view()),
]
然后您可以像这样从URI导入
import_urlconf.from_uri("/urlconf/")
示例用例
在Lyst,我们有3个服务生成Lyst网站URL
- 电子邮件服务。
- 网站地图生成服务。
- 付费广告购买服务。
这些服务在启动时从Lyst网站获取URLconf,并定期更新。
因此,当URL发生变化时,我们不需要更新任何服务代码。这在我们为本地化URL添加新语言时特别有用。
集成
从Django服务导出
在大多数情况下,最佳做法是从端点提供URLconf。
在某些情况下,如果您将URLconf保存到文件,可能效果更好。
如果您有这些方法都无法处理的专业用例,您可以自行实现核心逻辑以将URLconf导出为JSON。
如果您开发的自定义集成可能对他人有用,请随时提交PR。
在非Django服务中导入
您可以在任何Python代码中导入URLconf并创建URL。
首先,将Django作为依赖项添加,例如 pip install django
然后在导入任何URLconf之前调用 import_urlconf.init_django()
,例如。
from django_urlconf_export import import_urlconf
import_urlconf.init_django()
import_urlconf.from_uri("https://www.example.com/urlconf/")
然后您可以通过调用 reverse
来为您的网站创建URL,就像在网站代码中一样。
边缘情况
默认情况下,Django将与 settings.ROOT_URLCONF == "imported_urlconf"
初始化
在导入一些urlconf时将创建该模块。
如果您需要将 settings.ROOT_URLCONF
设置为不同的模块名称,您可以通过以下方式设置
import_urlconf.init_django(ROOT_URLCONF="another_urlconf_module")
您也可以以这种方式设置其他Django设置。
有关默认Django设置的源代码,请参阅源代码。
在具有自定义URL的Django服务中导入
默认情况下,库将URLconf导入到服务的根URLconf模块 - settings.ROOT_URLCONF
。
但如果服务有自己的URL,settings.ROOT_URLCONF
中可能已经包含了一些URLconf。
为了避免覆盖服务URL,您可以通过此Django设置导入不同的模块
URLCONF_IMPORT_ROOT_URLCONF = "imported_urlconf"
或者您可以在导入时添加一个 urlconf="..."
参数
import_urlconf.from_file("urlconf.json", urlconf="imported_urlconf")
如果模块不存在,则会自动创建,因此您可以随意命名。
如果模块已存在,现有的 urlpatterns
将会被覆盖。
然后您可以创建一个类似的 URL
reverse("login", urlconf="imported_urlconf")
或者为了方便,您可以创建一个如下的 website_urls.py
模块
from django import urls as django_urls
from django.apps import AppConfig
from django_urlconf_export import import_urlconf
class WebsiteURLsAppConfig(AppConfig):
name = "website_urls"
verbose_name = "Make URLs for our website in any Django service."
def ready(self):
"""
When Django initializes, get the latest urlconf from our website.
"""
update_urlconf()
def update_urlconf():
"""
Download the latest urlconf from our website
"""
import_urlconf.from_uri("https://www.example.com/urlconf/", urlconf="imported_urlconf")
def reverse(*args, **kwargs):
"""
Thin wrapper for Django's reverse method, to make a URL for our website.
"""
return django_urls.reverse(*args, urlconf="imported_urlconf", **kwargs)
将 "website_urls.WebsiteURLsAppConfig"
添加到 Django 设置中的 INSTALLED_APPS
,当 Django 启动时将导入 URLconf。
然后您可以调用 website_urls.reverse(...)
来为您的网站创建 URL。
如果您稍后想更新 URLconf,可以调用 website_urls.update_urlconf()
。
在没有URL的Django服务中导入
如果您的 Django 服务没有自己的 URL,可以将导入的 URLconf 存储在默认 URLconf 模块中 - settings.ROOT_URLCONF
。
这使事情变得简单一些。您可以创建一个如下的 website_urls.py
模块
from django.apps import AppConfig
from django_urlconf_export import import_urlconf
class WebsiteURLsAppConfig(AppConfig):
name = "website_urls"
verbose_name = "Make URLs for our website in any Django service."
def ready(self):
"""
When Django initializes, get the latest urlconf from our website.
"""
update_urlconf()
def update_urlconf():
"""
Download the latest urlconf from our website
"""
import_urlconf.from_uri("https://www.example.com/urlconf/")
将 "website_urls.WebsiteURLsAppConfig"
添加到 Django 设置中的 INSTALLED_APPS
,当 Django 启动时将导入 URLconf。
然后您可以调用 reverse()
并为您的网站创建 URL,就像在网站代码中一样
from django.urls import reverse
reverse(...)
如果您稍后想更新 URLconf,可以调用 website_urls.update_urlconf()
。
功能详情
如果您喜欢阅读代码而不是文档,测试中包含了所有功能细节的示例
导出白名单和黑名单
默认情况下,所有 URL 都会被导出。但您可以使用这些 Django 设置设置白名单和/或黑名单
URLCONF_EXPORT_WHITELIST = {"only-show-this-url"}
URLCONF_EXPORT_BLACKLIST = {"hide-this-url", "hide-this-one-too"}
首先应用白名单,然后应用黑名单。
列表项可以是正则表达式,例如 "secret-."
匹配所有以 secret-
开头的 URL 名称,如 secret-page-1
、secret-page-2
等。
白名单和黑名单集合是 URL 名称、URL 命名空间的混合
- URL 名称
- URL 命名空间
对于包含 namespace
(请参阅 Django 文档)的 URL,例如 Django 管理员 URL,列表必须同时允许 namespace
和 url_name
。
因此,您可以使用 blacklist = {"admin"}
禁止 admin
命名空间中的所有 URL。
如果您想导出 admin:some-url
但不导出其他 admin
URL,请设置 whitelist = {"admin", "some-url"}
。
注意:如果您设置 whitelist = {"admin"}
,则 不会导出任何管理员 URL。
有关更多示例,请参阅 单元测试。
您可以通过这种方式检查白名单和/或黑名单是否按预期工作
print(export_urlconf.get_all_allowed_url_names())
您也可以在导出为 JSON 时显式设置白名单或黑名单
export_urlconf.as_json(
whitelist={"only-show-this-url"},
blacklist={"hide-this-url", "hide-this-one-too"}
)
或者当生成文件时
django-admin export_urlconf_to_file \
--whitelist 'only-show-this-url' \
--blacklist 'hide-this-url", "hide-this-one-too' \
> urlconf.json
或者当从端点提供服务时
urlpatterns = [
url(r"^urlconf/", URLConfExportView.as_view(
whitelist={"only-show-this-url"},
blacklist={"hide-this-url", "hide-this-one-too"}
)),
]
包含的URL
我们完全支持包含的 URLconf。JSON 看起来像这样
{
"regex": "^colors/",
"namespace": None,
"app_name": None,
"includes": [
{"regex": "^red/$", "name": "red"},
{"regex": "^blue/$", "name": "blue"}
],
}
I18n URL
我们完全支持国际化 URL。
JSON 看起来像这样
{
"regex": {
"en-us": "^color/$",
"en-gb": "^colour/$",
"fr-fr": "^couleur/$"
},
"name": "color"
}
一些网站(例如 Lyst)只在语言家族级别本地化 URL。
例如,使用 en
而不是 en-us
和 en-gb
。
如果您设置此 Django 设置
URLCONF_EXPORT_LANGUAGE_WITHOUT_COUNTRY = True
则得到如下 JSON
{
"regex": {
"en": "^color/$",
"fr": "^couleur/$"
},
"name": "color"
}
您还可以在导出为 JSON 时添加一个参数
export_urlconf.as_json(language_without_country=True)
或者当生成文件时
django-admin export_urlconf_to_file --language-without-country > urlconf.json
或者当从端点提供服务时
urlpatterns = [
url(r"^urlconf/", URLConfExportView.as_view(language_without_country=True)),
]
我们支持 LocalePrefixPattern
(请参阅 Django 文档)。
因此,如果您有如下的 URLconf
from django.conf.urls.i18n import i18n_patterns
urlpatterns = i18n_patterns(
url(r"^$", View.as_view(), name="index"),
)
则得到如下 JSON
{
"isLocalePrefix": True,
"classPath": "django.urls.resolvers.LocalePrefixPattern",
"includes": [
{"regex": "^$", "name": "index"}
],
}
请注意,classPath
被保存在 JSON 中。因此,如果(像 Lyst 一样)您的项目使用 Django 的 LocalePrefixPattern
的子类,它将正常工作。
导出非默认根URLconf
默认情况下,我们导出创建 Django 网站端点的根 URLconf 模块:settings.ROOT_URLCONF
。这几乎总是您想要的。
如果您需要从不同的根 URLconf 模块导出,可以使用此 Django 设置
URLCONF_EXPORT_ROOT_URLCONF = "path.to.non_default_root_urlconf"
或者当导出为 JSON 时
export_urlconf.as_json("path.to.non_default_root_urlconf")
或者当生成文件时
django-admin export_urlconf_to_file \
--urlconf 'path.to.non_default_root_urlconf' \
> urlconf.json
或者当从端点提供服务时
urlpatterns = [
url(r"^urlconf/", URLConfExportView.as_view(
urlconf="path.to.non_default_root_urlconf",
)),
]
I18n URL的质量保证
此库在您有国际化 URL 时特别有用。
我们提供了一些方法来帮助确保 URL 正确翻译。
检查URL模式中的翻译错误
如果您想检查 URL 模式 kwargs 对于 URL 的所有翻译都是相同的,您可以在项目中添加一个单元测试
from django_urlconf_export import urlconf_qa
def test_for_url_translation_errors():
urlconf_qa.assert_url_kwargs_are_the_same_for_all_languages()
确保URL模式使用kwargs,而不是args
Django 允许您创建具有位置参数(args
)和/或命名关键字参数(kwargs
)的 URL 模式。
这种灵活性可能会导致混淆,尤其是在大型团队中。因此,确保开发人员只使用 kwargs
而不是 args
可能很有帮助。
将使用kwargs
的URL进行翻译也更容易避免错误,因为翻译者可以自由地更改URL中kwargs
的顺序以匹配其语言中的单词顺序。
例如,在Lyst,我们有如下URL:
示例URL | 本地化URL模式 | |
---|---|---|
英语 | /gucci-bags |
/(?P |
法语 | /sacs-gucci |
/(?P |
为了强制URL模式始终使用kwargs
而不是args
,请添加如下测试:
from django_urlconf_export import urlconf_qa
def test_all_urls_use_kwargs():
urlconf_qa.assert_all_urls_use_kwargs_not_args()
开发指南
运行测试
pip install tox
(或pip3 install tox
)
然后运行tox
开发
pip install --user pipenv
(或pip3 install --user pipenv
)
然后运行
pipenv install
pipenv shell
退出
pipenv --venv
将显示虚拟环境的位置。
这是在PyCharm中使用此venv的指南。
更改测试依赖
您需要运行pipenv install {new-dependency}
,并在tox.ini
中添加依赖项。
格式化导入和代码
首先运行pipenv shell
然后运行
isort
- 格式化导入black src/ tests/
- 格式化代码
然后运行exit
退出shell。
发布到PyPi
创建一个新版本,该包将自动通过GitHub操作发布。
进一步开发
如果能够使用此库生成的JSON在JavaScript中创建URL会很好。这样我们就可以在前端和在Node服务中创建URL。
Lyst目前没有在这方面工作。如果这个功能对您有用,非常欢迎您提交PR :)
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源代码发行版
构建发行版
哈希值 for django_urlconf_export-1.1.1-py3-none-any.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 4e431d51a292d4d04476a7a3a84377ffac45c8723cc7c86bd37b948238d1a635 |
|
MD5 | 515e672fc57e40817d292591476f2822 |
|
BLAKE2b-256 | 324fa1b7ab8a7cb6c8b29366a3eeadbe2ea5eaaadf78647eef8b178552184875 |