通过对url的定义转换、传参、命名等,找到相关的view,也就是它的处理函数.
路由就是关联url,及其处理函数关系的过程。
在django框架中,在settings.py文件中的ROOT_URLCONF变量,指定了全局的路由文件名称。
所以对于一个工程来讲,找到settings.py中的ROOT_URLCONF变量,就能知道工程的第1个入口的路由文件在哪里。
找到了入口的路由文件之后,打开它,就是uIs.py。
可以看到其中一个变量叫urlpatterns,这个变量是django工程预定的一个变量值。
该变量是列表类型,表示的就是url中的每一个路由的定义关系,其中的元素采用path()和re_path()两个函数来组成。
如图,我们写的msggate, 这样的路径,对应到一个include函数中。
另外admin对应到了一个处理函数,django的url路由有以下的一些流程:
对于django框架来讲,接受到了一个url请求之后,首先对于一个新的url要求,django将查询全局的urlpatterns自变量,并且在这个变量中按照先后顺序逐一比对,其中的urlpatterns的每个元素,urlpatterns是一个列表,列表是一个序列类型,它是有序的。
因此可以按照顺序从前向后的查找,每一个路由元素,当找到第1个匹配时,就停止查找,将匹配的结果中的那个处理函数返回回来。
如果没有查找到匹配,会出现异常,django会进行错误处理,这里面我们需要注意,django的路由并不考虑HTTP的请求方式,它仅根据url进行路由,换句话说我们知道在HTTP请求中,我们可能关联的是pos或者get这样的请求方式,
一共有7种甚至更多的请求方式,但是对django框架来讲,对django的路由来讲,他并不关心这些。
它对于同一个url,它就会指定到同一个操作函数中,路由的每一个元素,采用path()和re_path()函数来进行处理。
其中path()函数处理字符串类型的路由,而re_path()函数处理正则表达式类型的路由。
这两个路由函数,它的参数是相似的,主要参数有两个。
第1个参数是路径,对于path()来讲,它使用url字符串作为路径。
而re_path()这个路径中一定要包含正则表达式。正则表达式,可以理解为是字符串的一种模式。
第2个参数就是对应的处理函数,我们叫它view。
对于路由我们要知道,首先我们要给出一个路径,其次要给出它对应的操作函数。
具体来看一下,我们以path()为例,有4个参数,除了我们介绍的route、view之外,还有两个参数。
route参数,指的是url或url的模式,在django里,也包含它定义的url转换语法。
view指的是处理函数或视图函数,只要给他名称就可以,此外也可通过include来加载更多的录用信息。
第3个参数是一个字典类型,它向路径,提供额外的参数信息,额外的参数,将给到我们的处理函数,或者叫视图函数,中作为它的参数。
最后name指的是这个url模式的名字,给它命个名。
看几个实例:
这些都是url的定义的路由中的urlpatterns,这里面有articles/2003/这样的字符串。
也有articles,后面加了一些尖括号,尖括号里面有int:year这样的一种表达形式,
那么它到底是什么呢?django框架,支持三种方式来表达route,也就是表达路径的格式。
第1种叫精确字符串格式,顾名思义,就是给定url的精确字符串,那么在路由中匹配这个字符串,并且找到相关的处理函数。
第2种方式是django转换格式,这种转换格式采用的是<类型:变量名>的形式,这是一种转换格式,我们从它来提取参数。
第3种形式就是正则表达式格式,正则表达式来表示一类的url。
精确字符串格式:一个精确url匹配-一个操作函数,也是最简单的形式,它对应的是静态的urI的响应。
这里面需要注意一-点,当我们去表达路径的时候,Url字符串的最开始是不需要分隔符的,而结束是需要分隔符。
按照这样的约定,我们就可在设计urI的时候将所有的url自动的连接在一起。
所以最后一定要加上一个分隔符结尾。
那么django转换格式在对请求要进行处理的时候,使用了一个url模板,
这个模板呢不仅能够匹配请求url,还能将这个urI中的一部分提取出来作为参数。
什么意思呢?大家想想,我们在使用精确url进行路由的时候,用户请求的一个url,我们找到了他的一个处理函数,
但是如果用户请求url中的部分,我想作为参数或者作为变量传递给后面的函数的时候怎么办呢?
我们需要在url中将他的部分的信息变成参数,那么就需要一种模板,这就是django的转换格式所完成的作用。
django转换格式也是一种常用的表达路径的形式,他的目的就是通过对url的解析进行参数获取,并且进行参数传递。
它采用的基本形式就是<类型:变量名>,。比如用户的一个请求,要是articles/2018/,
而我们定义的表达路径的信息是articles/<int:year>,那么我们就能得到这样一个结果,
首先请求url,跟我们定义的路径是相匹配的。
因为它这里面包含了articles,也包含了第2个字段。同时呢我们能在这里边提取一个变量,这个变量叫year
它的 类型是int,那么这个变量值是2018,这里边django的转换格式中一共定义了5种处理urI的类型。
默认是string类型,它指的是匹配分隔符以外的非空字符串。
第2种转换格式类型是int型。也就是说将url中的一部分解析为整数,这里边指的整数是正整数和0,
比如刚才的2018,那么就转换成了year的变量,它的值是2018的整数。
第3个类型叫slug,它匹配字母、数字、减号和下划线。由他们组成的字符串就将slug类型,事实上它是字符串类型的一个子集。
第4种类型呢是叫uuid类型,它匹配.特定的uuid格式。
最后是path类型,只匹配任何的非空字符串,也包括路径的分割符等等,它是一个全集的表达的类型。
我们看第四行的路由信息,
它包含4个单元,也就是由分隔符分割的4个部分。我们请求url也是4个部分,所以他俩在部分上是精确匹配的。
匹配之后,这一行路由信息可以从请求的url号中提取出三个参数,一个year,它的类型是int,对应于请求的2018。
提取第二个参数是month,也是int类型对应01
第三个提取一个slug类型,其实是一种字符串类型的子集,它的变量名是msg
那么提取了三个参数之后,这三个参数就将作为view,也就是处理url函数的参数传递给后面的函数。
所以我们当我们去定义后边对url处理函数的时候,就可以默认的给出三个参数。
通过这个例子,大家应该看到,django的转换格式,事实上就是对url变量的一种提取,并且希望后面的转化函数可以通过更多的参数进行更丰富的处理。
route的表达还有第三种方式,就是正则表达式格式。
正则表达式是一种非常丰富的表达字符串的语法形式,它可以表达一类url,不是一个,而是一类,我们可以通过<>来提取变量,作为处理函数的参数,将正则表达式也能转换成提取参数的形式。
但是无论我们用什么样的表达方式,只要我们使用了字符串,使用了正则表达式,就需要使用re_path()函数。
在使用中则表达式的时候呢,它也有两种具体形式,可以通过简单形式,不提取任何参数。
比如artis/(【0-9】{4})/指的是0到9作为一个字符。四个字符,它可以表示匹配类这样的字符串,或者我们可以将正则表达式定义一个命名、定义一个变量,
那么它的格式如下图:
它指的是在这一部分提取一个变量,
它的变量名字是year。那么它的变量形式是0到9的字符,重复四次。那么通过正则表达式来提取的字符串类型,
统一是字符串,不能是其它类型。
我们看一个例子,还是请求url是2018/01learn-django-mooc。我们定义了这样的一个路由表达。我们看第三行,第三行呢从artis开始,匹配了四个部分,与用户请求的url一致。其中三个部分都采用了正则表达式的形式进行相关提取。提取之后,第一个变量year,它的值是一个字符串类型。第二个monrh也是字符串类型,第三个msg 也是字符串类型。也就是说如果使用正则表达式的方式,从url中提取变量,它只能提取字符串类型。
我们再总结一下。route有三种表达格式,可以是精确的字符串,或者是django的转换格式类型,或者是正则表达式的格式类型。那么对于path函数,我们讲解了第一个参数route。那么它的重要的第二个参数就是view,也就是处理或者视图函数。
那么第二个参数的viewl的使用包含两种主要类型。第一种就是处理函数,它指的是处理url的对应函数,也是每一个url处理的最终归宿。那么view还有第二种参数形式,就是include的函数,在一个路由信息中包含其它路由文件或者路由信息。
那么他不仅可以形成路径的组合,他有更多的作用。
我们看一个实例,在主路由文件中,我们定义的路径是entry,它包含了一个路由文件。那么在第二个路由文件中,我们设定了help跟sub两个路径,那么使用include的方式,将不同路由信息组合起来的时候,它的路径也是分段组合形成总路径。
像这样的include包含局部路由文件之后,我们事实上用户访问的时候,他访问的总路径是entry/help对应的是help函数,entry/sub的是sub处理函数,include除了附加本地路由之外,还有一个非常有趣的作用,它就是路径去重。
比如说众多的路由他们的前缀或者有路径的前一部分是相同的,我们就可以用include的方法,将他们公用的路径提取出来。
这样当你的路由体系非常庞大的时候,能使用include函数将减少你的代码修改,或者让你的代码降低它的出错概率。
那么下面呢我们介绍一下url的根目录的处理。记得我们之前跑过的实例,当我们生成一个APP之后,打开127.0.0.1:8000/时网页反馈说找不到当前的响应文件。
那么下面我们可以增加一个相应文件。那具体做法呢很简单,就是在我们的主路径文件中增加路径path,它的路径是什么呢?就是空的。空路径对应的就是根目录的处理函数,我们也可以正则表达式^$表示空。
这两者路径的路由使用其中一个就可以。看大家自己的兴趣。
原文: