Django 路由模型
2018-08-30 本文已影响0人
vckah
基于 Django 1.11
Django 默认会创建后台管理的 url url('admin/', admin.site.urls)。之后可以自定义 url。
url 分类
- 普通 url 映射,直接写 url,然后引入对应函数即可
- 动态 url 映射,需要自己写正则表达式那种,即参数里面有变量,如
url(r'^bookinfo/(\d+)/$', views.xxx) - 两级 url 映射,Django 为了分层,可以在每个
app下新建自己的 url 文件,然后在项目主url.py中使用include即可
Django 默认会找 settings.py 文件中定义的 ROOT_URLCONF,找到根 url 之后,开始解析 url。
url 函数源码:
def url(regex, view, kwargs=None, name=None):
if isinstance(view, (list, tuple)):
# For include(...) processing.
urlconf_module, app_name, namespace = view
return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace)
elif callable(view):
return RegexURLPattern(regex, view, kwargs, name)
else:
raise TypeError('view must be a callable or a list/tuple in the case of include().')
在 url 函数中如果直接跟一个函数对象或者类的 as_view()方法,那么会返回 RegexURLPattern 对象。如果是一个列表或者元组,那么返回一个 RegexURLResolver ,这种情况就是包含 include 的情况,否则抛出异常。
RegexURLPattern 和 RegexURLResolver 都返回一个 ResolverMatch 对象,它里面会调用对应的函数。
RegexURLResolver 首先会匹配根 url 中定义的 url 前缀,然后去 include 对应的文件中去找,可以去看看它的 resolve 函数实现,找不到会抛出一个 Resolver404 异常。
来看一看具体的调度过程:
url 调度过程
从图中我们也可以发现一个问题,Django 项目不适合做 url 非常多的项目,因为匹配 url 是扫描一个列表的,当 url 规模达到一定量级的时候,扫描这样的一个列表是非常耗时的。
改进方法:利用 lru 在系统中维护一个 url 的缓存系统。可以将 url 做哈希之后与对应的 view 函数对应。