如何在Django中程序化添加URL模式?
有没有办法在不重启服务器的情况下,程序matically地给Django添加网址模式?
或者有没有办法强制Django重新处理或缓存网址模式(URLconf)?
4 个回答
3
这是你的答案:
import sys
from django.conf import settings
from importlib import reload
from django.urls import clear_url_caches
urlconf = settings.ROOT_URLCONF
if urlconf in sys.modules:
clear_url_caches()
reload(sys.modules[urlconf])
3
我尝试过一些方法,修改了 django.core.urlresolvers
里的东西——这对我有效,但要注意这只是个小技巧。我现在没有代码了,但大概做了以下几步:
- Django 通常使用
urlresolvers.get_resolver()
来获取一个RegexURLResolver
,这个东西负责处理网址。把None
传给这个函数可以得到你的“根” URL 配置。 get_resolver()
会使用一个缓存,叫_resolver_cache
,来存储加载过的 URL 配置。- 重置
_resolver_cache
应该能强制 Django 重新创建一个干净的 URL 解析器。
另外,你也可以试着取消根 RegexURLResolver
的 _urlconf_module
属性,这样应该能强制 Django 重新加载它(不过我不太确定,因为这个模块可能会被 Python 缓存)。
from urlresolvers import get_resolver
delattr(get_resolver(None), '_urlconf_module')
再次强调,这个方法不一定有效(我只是凭记忆说的,之前的代码我显然是出于某种原因删掉了)。但 django/core/urlresolvers.py
绝对是你需要查看的文件。
编辑:我决定试试这个,但结果没有成功……
编辑2:
果然,你的 URL 模块会被 Python 缓存。简单地在它们变化时重新加载可能有效(使用 reload
)。如果你的问题是根据一些可能变化的数据动态构建 urlpatterns
。
我尝试了重新加载我的根 URL(project.urls)和一个子 URL 模块(app.urls)。这就是我需要做的,新的 URL 就能通过 get_resolver(None).url_patterns
显示出来。
所以这个小技巧可能就是这么简单:手动重新加载你的 URL 模块。
4
如果你使用gunicorn而没有预加载代码,只需给gunicorn的主进程发送一个HUP信号,它就会启动新的工作进程来加载新代码,同时优雅地关闭旧的工作进程,这样就不会丢失任何请求!