路由层

路由层

路由:

请求地址与视图函数之间的映射关系!
urlpatterns = {
    url(regex, view, kwargs=None,name=None)
}
url()  : 本质是一个函数
regex : 正则表达式,匹配url地址的路径部分
  eg: http://127.0.0.1:8080/index/ (匹配index部分)
            
view: 通常为视图函数,处理业务逻辑
kwargs :  有名分组(name=正则表达式匹配到的内容))
name   :  反向解析(路由与视图函数对应关系起别名)

路由匹配

路由匹配:
# 取消django自动让浏览器加斜杠的功能
APPEND_SLASH = False  # 该参数默认是True

urlpatterns = [url(r'^admin/', admin.site.urls),  # url第一个参数是一个正则表达式
               
url(r'^test/$', views.test),  # 一旦正则表达式能够匹配到内容 会立刻结束匹配关系 直接执行后面对应的函数

# django匹配路由的规律
# 不加斜杠 先匹配一次试试 如果匹配不上 会让浏览器重定向 加一个斜杠再来一次 如果还匹配不上 才会报错
匹配:
1.路由匹配值匹配url部分
2.不匹配?后面的get携带的参数

分组

通过一个条件(eg:id),浏览器在发送请求时,需要向后台传递参数(id),http://127.0.0.1:8000/article/?id=3,亦可直接http://127.0.0.1:8000/article/3/;
 针对后一种方式django就需要直接从路径中去参数,用到正则表达式的分组功能!!
正则匹配(^  / $ )   : 从xx开始到xx结束

无名分组:
	将分组内正则表达式匹配到的内容当做位置参数传递给视图函数
    url(r'^test/([0-9]{4})/', views.test)
 #报错:test() takes 1 positional argument but 2 were given   传入两个参数,接收仅仅一个

#	当你的路由中有分组的正则表达式  那么在匹配到内容,执行视图函数的时候 会将分组内正则表达式匹配到的内容当做位置参数传递给视图函数  	
test(request,分组内正则表达式匹配到的内容)


有名分组:

	会将分组内的正则表达式匹配到的内容当做关键字参数传递给视图函数
url(r'^testadd/(?P<year>d+)/', views.testadd),
# 匹配的d+数据,他的key为year

# testadd() got an unexpected keyword argument 'year'

# 当你的路由中有分组并且给分组起了别名 那么在匹配内容的时候,会将分组内的正则表达式匹配到的内容当做关键字参数传递给视图函数  testadd(request,year=分组内的正则表达式匹配到的内容)

利用有名和无名分组 我们就可以在调用视图函数之前给函数传递额外的参数

url(r'^index/(d+)/(?P<year>d+)/', views.index),
	
不能混合使用!!!,但是同一种分组的情况下 :
	可以使用多次 
	无名可以有多个
	有名可以有多个
	但是就是不能混合使用
url(r'^index/(d+)/(d+)/', views.index),
url(r'^index/(?P<args>d+)/(?P<year>d+)/', views.index)

反向解析:

根据一个别名 动态解析出一个结果 该结果可以直接访问对应的url

第一种情况:
路由中没有正则表达式 直接是写死的
url(r'^home/', views.home,name='xxx'),  # 给路由与视图函数对应关系起别名

前端反向解析:
	{% url 'xxx' %}
后端反向解析:
from django.shortcuts import render,HttpResponse,redirect,reverse
	url = reverse('xxx')

第二种情况:
	无名分组的反向解析 在解析的时候 你需要手动指定正则匹配的内容是什么
	url(r'^home/(d+)/', views.home,name='xxx'),  # 给路由与视图函数对应关系起别名
			
前端反向解析:
<p><a href="{% url 'xxx' 12 %}">111</a></p>

后端反向解析:
	url = reverse('xxx',args=(1,)) #元组
-# 手动传入的参数 只需要满足能够被正则表达式匹配到即可

第三种情况:
	有名分组的反向解析 在解析的时候 你需要手动指定正则匹配的内容是什么
	有名分组的反向解析可以跟无名分组一样
最正规的写法:
url(r'^home/(P<year>d+)/',views.home,name='xxx'),  # 给路由与视图函数对应关系起别名

前端:
# 可以直接用无名分组的情况
<p><a href="{% url 'xxx' 12 %}">111</a></p>

后端:
# 可以直接用无名分组的情况
url = reverse('xxx',args=(1,))
以编辑功能为例
				url(r'^edit_user/(d+)/',views.edit_user,name='edit')
def edit_user(request,edit_id):
	# edit_id就是用户想要编辑数据主键值
	pass			
{% for user_obj in user_list %}
<a href='/edit_user/{{user_obj.id}}/'>编辑</a>
<a href='{% url 'edit' user_obj.id %}'>编辑</a>
{% endfor %}

路由分发:

在django中所有的app都可以有自己独立的urls.py  templates static;正是由于上面的特点 你用django开发项目就能够完全做到多人分组开发 互相不干扰;每个人只开发自己的app
	小组长只需要将所有人开发的app整合到一个空的django项目里面;然后在settings配置文件注册 再利用路由分发将多个app整合到一起即可完成大项目的拼接
    
 --  路由分发解决的就是项目的总路由匹配关系过多的情况

原理:	使用路由分发 会将总路由不再做匹配的活 而仅仅是做任务分发(请求来了之后 总路由不做对应关系,只询问你要访问哪个app的功能 然后将请求转发给对应的app去处理)


from app01 import urls as app01_urls
urlpatterns = [url(r'^admin/', admin.site.urls),  # url第一个参数是一个正则表达式
# 路由分发
url(r'^app01/',include(app01_urls)),  # 路由分发需要注意的实现 就是总路由里面不能以$结尾

简写:url(r'^app01/',include('app01.urls'))

名称空间;

当多个app中出现了起别名冲突的情况 你在做路由分发的时候 可以给每一个app创建一个名称空间;
	然后在反向解析的时候 可以选择到底去哪个名称空间中查找别名;
url(r'^app01/',include('app01.urls',namespace='app01')),

# 后端:
	print(reverse('app01:reg'))
# 前端:
	<a href="{% url 'app01:reg' %}"></a>

只需要保证起别名的时候 在整个django项目中不冲突即可!
起别名的时候统一加上应用名前缀
	urlpatterns = [						url(r'^reg/',views.reg,name='app02_reg')

django版本区别:

2.x  : path   第一个参数不是正则,不支持正则 ,写啥匹配啥
       re_path == usl(1.x)  支持正则 5中类型转换器:能将类型转换不同类型,自定义

1.x  : url    第一个参数是正则,支持正则
              只有字符串一种,要转就强制转
原文地址:https://www.cnblogs.com/shaozheng/p/11929817.html