Django 路由模型

基于 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 的情况,否则抛出异常。

RegexURLPatternRegexURLResolver 都返回一个 ResolverMatch 对象,它里面会调用对应的函数。
RegexURLResolver 首先会匹配根 url 中定义的 url 前缀,然后去 include 对应的文件中去找,可以去看看它的 resolve 函数实现,找不到会抛出一个 Resolver404 异常。

来看一看具体的调度过程:


url 调度过程

从图中我们也可以发现一个问题,Django 项目不适合做 url 非常多的项目,因为匹配 url 是扫描一个列表的,当 url 规模达到一定量级的时候,扫描这样的一个列表是非常耗时的。
改进方法:利用 lru 在系统中维护一个 url 的缓存系统。可以将 url 做哈希之后与对应的 view 函数对应。

你可能感兴趣的:(Django 路由模型)