注:以下内容转载自 现代魔法学院 网站的 URLconf处理其五:URL调度过程实例 一文,仅供学习使用。
下面举一个具体的例子将加深对 RegexURLResolver.reslove() 调用的理解。假设工程名为 mysite,并且创建了 app people。
1. mysite.urls.py
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r"^$","mysite.views.index"),
url(r"^about/","mysite.views.about"),
url(r"^people/",include(people.urls)),
url(r"^contact/","mysite.views.contact"),
url(r"^update/","mysite.views.update"),
)
2. people.urls.py
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r"^NowaMagic/","people.views.NowaMagic"),
url(r"^sam/","people.views.sam"),
url(r"^jenny/","people.views.jenny"),
)
3. people.views.py
def NowaMagic(request):
return HttpResponse("Hello NowaMagic")
当访问 http://exapmle.com/people/daoluan/ 的时候 URL dispatcher 的调度过程(蓝色部分):
1. BaseHandler.get_response() 中根据 settings.py 中的 ROOT_URLCONF 设置选项构造 RegexURLResolver 对象, 并调用 RegexURLResolver.resolve("/people/daoluan/") 启动解析, 其中 RegexURLResolver.regex = "^\", 也就是说它会过滤 "\", url 变为 "people/daoluan/";
2. resolve() 中调用 RegexURLResolver.url_patterns(), 加载了所有的匹配信息如下(和图中一样):
- (类型)RegexURLPattern (正则匹配式)[^$]
- RegexURLPattern [^about/]
- RegexURLResolver [^people/]
- RegexURLPattern [^contact/]
- RegexURLPattern [^update/]
3. 下一个 pattern 过程同上.
4. 第三个 pattern 因为是 RegexURLResolver 对象, 所以 resolve() 调用的是 RegexURLResolver.resolve(),而非上面两个例子中的 RegexURLPattern.resolve()。因为第三个 pattern.regex = "^people/",所以会将 "people/daoluan/" 过滤为 "daoluan/". pattern.resolve() 中会调用 RegexURLResolver.url_patterns(), 加载了所有的匹配信息如下(和图中一样):
- RegexURLPattern [^daoluan$]
- RegexURLPattern [^sam$]
- RegexURLPattern [^jenny$]
语句 for pattern in self.url_patterns: 开始依次匹配。第一个就中, 过程和刚开始的过程一样. 因此构造 ResolverMatch 对象返回. 于是 BaseHandler.get_response() 就顺利得到 ResolverMatch 对象, 其中记录了有用的信息。在 BaseHandler.get_response() 中有足够的信息让你知道开发人员在 views.py 中定义的函数是 def daoluan(request): 在什么时候调用的:
# BaseHandler.get_response() 的定义
# 处理请求的函数, 并返回 response
def get_response(self, request):
......
# 实例化 RegexURLResolver, 暂且将其理解为一个 url 的匹配处理器, 下节展开
resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
......
# 调用 RegexURLResolver.resolve(), 可以理解为启动匹配的函数; 返回 ResolverMatch 实例
resolver_match = resolver.resolve(request.path_info)
......
# resolver_match 对象中存储了有用的信息, 譬如 callback 就是我们在 views.py 中定义的函数.
callback, callback_args, callback_kwargs = resolver_match
......
# 这里调用的是真正的处理函数, 我们一般在 view.py 中定义这些函数
response = callback(request, *callback_args, **callback_kwargs)
......
return response
从上面知道,url 调度器主要 RegexURLResolver、RegexURLPattern、ResolverMatch 和三个辅助函数 url()、include()、patterns() 完成。可以发现,url 的调度顺序是根据 urls.py 中的声明顺序决定的,意即遍历一张表而已。