Django路由系统
一、urls文件中的映射关系格式
Django中的URL路径与业务函数的映射关系写在urls.py文件中,该文件只有一个变量urlpatterns,变量的值是一个列表,列表中的元素是一个个包含URL和处理函数的映射关系的元祖,其一般格式如下:
urlpatterns = [url(正则表达式, views视图函数,参数,别名),]
第一个参数是URL路径的正则字符串,第二个参数是一个视图函数(类)或者指定视图函数(类)路径的字符串,第三个参数可选的传给视图函数的默认参数且以{参数名:值}的形式,第四个参数可选的name值表示路径的别名
需要注意的是路由系统在匹配到一条映射关系后就不会继续匹配,所以越精确的映射关系越要放在前面,同时路由系统只会匹配URL中的路径部分,域名和参数不会参与匹配,URL以login.html、auth.html结尾Django会自动在路径尾部添加/
二、无名分组
映射关系中的URL正则字符串中的每个分组都会作为参数传给视图函数,并且是按位置传递的,参数的值都是字符串形式的。比如urlpatterns = [url(r'^articles/([0-9]{4})/$', views.year_archive),],标红的这个分组会被传给视图函数
三、有名分组
就是在分组的时候给每个分组起个名字,视图函数的形参以分组名命名,就可以实现按关键字传参,参数的值也是字符串。比如urlpatterns = [url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),],当分组名与视图函数默认参数同名时会使用分组捕获的值。
四、匹配根目录
映射关系中要匹配网站根目录需要按如下格式:urlpatterns = [url(r'^$', views.index),]
五、url映射
由于一个Django工程下可以有多个应用,如果所有应用的路由关系都写在一个urls文件中可能会导致一个应用出现问题影响其他应用的情况,为了避免这种情况出现需要给每个应用单独写一个urls文件取映射各自的视图函数,全局的urls文件只负责将某个应用的请求指向其对应的urls文件去匹配。
在全局的urls文件中做如下配置
from django.conf.urls import url, include
urlpatterns = [
url(r'^blog/', include('blog.urls')),
] blog就是该工程下的一个应用
六、URL反向解析
利用urls.py文件映射关系中的参数name给一个URL匹配规则起别名的方式,可以实现动态匹配URL。
在应用的urls.py文件按如下格式设计URL匹配记录:
from django.conf.urls import url from . import views urlpatterns = [ #... url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'), #... ] #news-year-archive就是这条匹配规则的别名,别名原则上在整个项目中必须唯一
在模板中可以使用别名获取对应的URL匹配记录:
<!--{% url '别名' 正则匹配部分1(分组名1=正则匹配部分1) 正则匹配部分2 ... %}--> <a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a> <ul> {% for yearvar in year_list %} <!--yearvar会被View中传入的值渲染--> <li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li> {% endfor %} </ul>
在Python代码中使用别名获取对应匹配记录需要django.core.urlresolvers.reverse() 函数:
from django.core.urlresolvers import reverse(django1.x)
from django.urls import reverse(django2.x) from django.http import HttpResponseRedirect def redirect_to_year(request): # ... year = 2006 # ... return HttpResponseRedirect(reverse('news-year-archive', args=(year,))) #(reverse(('别名'),args=(匹配规则参数1,匹配规则参数2,.....)))
七、CBV
之前的匹配记录都是URL路径对应一个函数,这是匹配规则的一种写法即FBV基于函数的View,可想而知,既然可以基于函数当然也可以基于类即CBV。
CBV的匹配规则按照如下格式写:
from django.conf.urls import url from . import views urlpatterns = [ #... url(r'^login.html$', views.Login.as_view()), #... ] #url(URL路径匹配规则, views.类名.as_view()),类名.as_view()会执行对应类的as_view方法结果是返回as_view方法内部的view函数的内存地址,所以当该匹配记录命中时其实是执行view函数然后由view函数调用dispatch方法
在views.py中按如下格式写:
from django.views import View class Login(View): #每个类必须继承View类 def dispatch(self, request, *args, **kwargs):#如果需要在执行父类的dispatch方法前后执行其他操作就重写dispatch方法但是必须继承父类的dispatch方法 print('before') obj = super(Login,self).dispatch(request, *args, **kwargs) print('after') return obj def get(self,request):#由父类的dispatch方法获取请求的方式,调用该类中相应的方法 return render(request,'login.html') def post(self,request): print(request.POST.get('user')) return HttpResponse('Login.post')

浙公网安备 33010602011771号