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')

 

posted @ 2017-10-23 16:11  魅力宁波  阅读(162)  评论(0)    收藏  举报