Django路由系统
序章
Django如何处理一个请求:
- 项目启动后根据settings 文件中 ROOT_URL_CONF 决定根URLconf
- 它是django.conf.urls.url() 实例的一个python列表
- Django 依次匹配每个URL模式,在与请求的URL匹配到第一个模式停下来。
- 一旦其中的一个正则表达式匹配上了,Django将导入并调用给出的视图,它是一个简单的python函数(或者一个基于类的视图)。视图将获得如下参数:
- 一个HttpRequest 实例
- 如果匹配的正则表达式返回了没有命名的组,那么正则表达式匹配的内容将作为位置参数提供给视图。
- 关键字参数由正则表达式匹配给的命名组成,但是可以被django.conf.urls.url()的可选参数kwargs覆盖。
- 如果没有匹配到正则表达式,或者过程中抛出异常,将调用一个适当的错误函数处理视图。
Django的URL和Views的配置哲学:松耦合,简单的说就是URL指定视图函数和视图函数的具体实现是在两个不同的地方,实现开发者修改一个配置而不影响另外一个配置。
路由系统的使用
路由系统的核心规则:匹配方式为自上而下,匹配到第一条就会忽略后面所有规则!所以路由的顺序很重要!
# urls from django.conf.urls import url, include from django.contrib import admin from myapp import views # 导入myapp项目中的view文件 from anotherapp import urls as otherurls urlpatterns = [ # admin管理页面 url(r'^admin/', admin.site.urls), # 默认页面,http://127.0.0.1 url(r'^$', views.index), # 登录页面, http://127.0.0.1/login/ url(r'^login/$', views.login, name='login'), # 动态路由(传递一个参数),常用用于urls过多,通过正则来完成,比如分页系统 ,小括号表示分组 url(r'^book1/(\d+)/$', views.book), # 动态路由(传递多个参数),传递两个数字给book1函数 ,url传递几个参数,后端函数就要接收几个参数,按序(位置)传参 url(r'^book2/(\d+)/(\d+)/$', views.book1), # 动态路由(key:value关键字形式),k1,k2即为关键字, k1是一个字符串,k2则是零个或一个数字 url(r'^book3/(?P<k1>[\w|-]+)/(?P<k2>\d*)/$', views.book2), # 二级路由,包含其他的urls路由, http://127.0.0.1/blog/下面所有的路径 url(r'blog/', include('blog.urls')), url(r'other/', include(otherurls)), ]
# views from django.shortcuts import render,HttpResponse def book1(request): return HttpResponse('book1') def book2(request,num): print(num) return HttpResponse('book2') def books3(request,k1,k2): print(k1,k2) return HttpResponse('book3')
# include 相当于二级路由策略,它接收到的url地址去除了它前面的正则表达式,将剩下的字符串传递给下一级路由进行判断。 建议:除了admin路由外,每个app都应该设计自己独立的二级路由 # url url()函数可以传递4个参数,其中2个是必须的:regex 和 view, 以及2个可选参数:kwargs和name。 regex: regex是正则表达式的通用缩写, 它是一种匹配字符串或url地址的语法。django通过用户请求地址,在urls.py文件中对urlpatterns列表中的 name: 可以用于templates,models,views,通过name获取对应的url网址,相当于给网址起一个别名,注意name不要重复。 # URL name 在template中的用法 <a href="{% url 'key_list' %}">主机管理</a> # 普通的url name示例 <a href="{% url 'group_list' args %}">分组管理</a> # url 需要传递参数的name示例 <a href="{% url 'app01:group' pk=11 pp=99 %}">分组查询</a> # 在代码层使用 v = reverse('app01:group', kwargs={'pk':11}) # 上面是html 文件的节选,在a标签中网址,使用的模板语言,模板中用的就是url name,这样用的好处就是即使网页地址变更,只要url name 不变就可以继续访问页面。
路由规则中的正则表达式:
.(dot) 任意单一字符 \d 任意一位数字 [A-Z] A 到 Z 中任意一个字符(大写) [a-z] a 到 z 中任意一个字符(小写) [A-Za-z] a 到 z 中任意一个字符(不区分大小写) + 匹配一个或更多(eg: \d+ 匹配一个或多个数字字符) [^/]+ 一个或多个不为'/'的字符 ? 零个或一个之前的表达式(eg:\d? 匹配零个或一个数字) * 匹配0个或更多(eg: \d* 匹配0个或更多数字字符) {1,3} 介于一个和三个(包含三个)之前的表达式(eg: \d{1,3}匹配一个或两个或三个数字)
反向解析URL:
- 在模板语言中:使用url 模板标签
- 在Python代码中,使用 reverse() 函数
- 在更高层的,处理Django模型实例相关代码中:使用 get_absolute_url() 方法
# 遇见的两种导解析方式 (1)第一种方式,绝对路径解析: from django.http import HttpResponseRedirect def f1(request): pass return HttpResponseRedirect('/classroom/notamember/%s/' % classname) (2)第二种方式,reverse from django.core.urlresolvers import reverse from django.urls import reverse def f2(request): pass url = reverse('notamember', kwargs={'classname': classname}) return HttpResponseRedirect(url)

浙公网安备 33010602011771号