django—路由层

1、路由匹配

1、url第一个参数是一个正则表达式,只要匹配到结果,就会立即执行对应的视图函数,不再往下匹配查找

2、在匹配请求url时,若不能匹配到结果,django会让浏览器重定向,url为原来的url加上/,如果还是匹配不到,就会返回404

3、只匹配url部分,不会匹配参数部分,如get请求携带参数?username='dadsadasd'

基于此,一般的url正则规则是:起始符^,加斜杠/,结束符&;如:

urlpatterns = [
    url(r'^admin/', admin.site.urls),  # 不添加结束符$,代表后面可以跟其他的url,不会限制死
    url(r'^login/$', views.login),  # 添加^、$符,代表只有login/能匹配到,不能多不能少
    url(r'^home/$', views.home),  # 这种情况下,请求home匹配不到,django重定向到home/即可匹配到
    url(r'^userlist', views.userlist),  # 这种情况下,请求userlistdasdad也能够匹配到,不严谨
    url(r'index/$', views.index)  # 这种情况下,请求asddsaindex也能匹配到
]

2、无名分组

1、url的正则匹配有分组,并且没有给它命名

2、使用分组接收多个参数时,参数时直接连在一起作为字符串进行正则匹配的,因此,传多个分组参数时,可能会出现前一个分组将第二个参数分割了,导致参数错误

3、django会将匹配到的分组内的字符串作为另外的位置参数传给视图函数,因此,对应的视图函数必须要定义位置形参或者用args接收它。如:

# urls.py
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^edit/(\d+)/', views.edit)
]

# views.py
def edit(request,*args):  # 可以接受多个位置参数,即多个正则分组
    print(args)

3、有名分组

1、url的正则匹配有分组,并且给它命名

2、同样,在多个分组解析参数时,可能会出现分组内容被前一个分组分割的情况,因此正则规则的设计至关重要

3、django会将匹配到的分组内的字符串作为另外的关键字参数传给视图函数,因此,对应的视图函数必须要定义同名参数接收它或者用kwargs接收。如:

# urls.py
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^edit/(?P<edit_id>\d+)/')
]

# views.py
def edit(request,**kwargs):  # 可以接受多个位置参数,即多个正则分组
    print(kwargs)

注意点:

在url路由层,不能同时使用有名分组和无名分组


4、反向解析

目的:使得在路由层之外,可以用变量引用的方式动态绑定url,便于维护,有利于程序扩展

实现:在url路由层,给url起别名,在路由层之外任何地方,可以通过这个别名解析出对应的url

根据url的正则匹配结果是否唯一来分情况处理:一般结果不唯一的部分都会被分组,所以此处按是否分组讨论


1、路由中的正则规则不包含分组

此时代表正则规则匹配结果唯一,如

url(r'^home/$', views.home,name='home')  #home/ 给起别名为home

# 前端反向解析:
<p><a href="{% url 'xxx' %}">111</a></p>  # 引用别名home
# 解析结果:<p><a href="home/">111</a></p>

# 后端反向解析:以视图层为例
from django.shortcuts import render,HttpResponse,redirect reverse
def xxx(request):
    url = reverse('home')  # 引用别名home,解析结果:/home/
    return redirect(url)  # 重定向到/home/



2、分组没有起别名

此时代表正则匹配结果不唯一,不唯一的部分被分组

在解析时需要手动输入一个参数使得,正则匹配分组部分也能匹配到结果如

url(r'^edit/(\d+)/',views.edit, name='edit')

# 前端反向解析:
{% url 'edit' 6666 %}  # 直接写一个符合正则的字符串

# 后端反向解析:
url = reverse('edit',args=(8888,))  # 以元组的形式传入一个符合正则分组规则的字符串


3、分组有起别名

可以直接用无名分组相同的方式

可以使用正规的方式,如下:

url(r'^edit/(?P<edit_id>\d+)/',views.edit, name='edit')

# 前端反向解析:
{% url 'edit' edit_id=6666 %}  # 直接写一个同分组名的关键字参数

# 后端反向解析:
url = reverse('edit',kwargs={'edit_id':8888}  # 以字典的形式传入,key与分组名同名


5、 路由分发

1、路由分发的来源

1、在django中所有的app都可以有自己的独立的urls.py,templaces,static
2、基于1,可以实现多人开发,互不干扰
3、最后只需要将所有人开发的app整合到一个空的django项目中,即可完成一个大项目
4、整合设置:注册app、路由分发

2、路由分发所做的事情

整合所有app后,如果将所有的app路由层都整合到一起,那么代码将会非常长,路由匹配过度

所以,使用路由分发,总路由不再做url与视图函数的匹配工作,而是将请求分发到对应的app,由对应的app处理请求的工作


3、实现

使用include方法,实现路由分发

方式一:导入各应用的urls

# 导入app的urls,为了区分不同的app,将不同app的urls起别名
from app01 import urls as app01_urls
from app02 import urls as app02_urls

# 是使用include方法,实现路由分发
urlpatterns = [
	url(r'^admin/', admin.site.urls),  # url第一个参数是一个正则表达式
    # 路由分发
    url(r'^app01/',include(app01_urls)),  # 总路由里面不能以$结尾
    url(r'^app02/',include(app02_urls)),
]

方式二:利用反射的原理,加上一些模块的帮助,直接分发到app

urlpatterns = [
	url(r'^admin/', admin.site.urls),  # url第一个参数是一个正则表达式
    # 路由分发
    url(r'^app01/',include(app01.urls)),  # 总路由里面不能以$结尾
    url(r'^app02/',include(app02.urls)),
]

6、名称空间

当多个app的路由层取的别名相冲突时,为了保证分发到正确的应用,有两种方式做区分

# app01的urls.py
urlpatterns = [
    url(r'^reg/',views.reg,name='reg')
]

# app02的urls.py
urlpatterns = [
    url(r'^reg/',views.reg,name='reg')
]

方式一:给每一个app创建名称空间,如:

urlpatterns = [
	url(r'^admin/', admin.site.urls), 
    # 路由分发
    url(r'^app01/',include(app01.urls),namespace='app01'),
    url(r'^app02/',include(app02.urls),namespace='app02'),   
]

# 前端反向解析:
{% url 'app01:reg' %}
{% url 'app02:reg' %}

# 后端反向解析:
url1 = reverse('app01:reg')
url2 = reverse('app02:reg')

方式二:规范起名,以app名开头

即给路由起别名的时候,就做好区分,以app名开头,如:

# app01的urls.py
urlpatterns = [
    url(r'^reg/',views.reg,name='app01_reg')
]

# app02的urls.py
urlpatterns = [
    url(r'^reg/',views.reg,name='app02_reg')
]

7、伪静态

搜索引擎在遇到html等静态文件时,将会收藏该文件,从而提高改页面的seo查询频率和搜藏力度

伪装方式:

# 给url起别名时,以.html等表示静态文件的方式结尾

8、虚拟环境

1、虚拟环境相当于一个python解释器

2、刚下载安装时,没有任何的模块包

3、一台机器上可以有多个

4、利用虚拟机,可以给每一个项目,只装备该项目所需要的模块,减少资源消耗


9、django版本区别

主要是django1与django2的区别

此处只谈在路由层的区别

django1用的是url方法实现路由匹配
django2用的时path方法和re_path方法实现路由匹配

django2中re_path方法与django1中的url方法,没有区别

django2中path方法与django1中的url方法的区别如下:
	1、path的第一个参数不是正则,也不支持正则,些什么就匹配什么
    2、path提供了5种转换器,能够将匹配到的数据转换成对应的数据类型,url没有
    3、除了默认的5种转换器,还支持自定义转换器
posted @ 2019-11-25 20:19  W文敏W  阅读(222)  评论(0编辑  收藏  举报