4、路由层
前言:路由层的作用
专业的说法:URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码对应执行。
通俗的说法:路由层就是用来介绍路由与视图函数对应关系的,我们写各种路由,就能通过URL去访问视图层里的视图函数(视图类)
一、路由匹配
# 路由匹配的本质就是正则匹配,正则匹配会引发一个问题,如下
url(r'test', views.test),
url(r'testadd', views.testad),
'''
这时候输入url后缀/test进入test页面
输入testadd进入的还是test页面
乱输入testasdadqwddad还是能进入test页面
qweqweqwasdtest也能进入test页面
'''
################################################################
# 所以正确的url书写方式如下
rlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^test/$', views.test),
url(r'^testadd/$', views.testad),
url(r'^$', views.home), # 默认的首页
]
# ^的意思是以什么开头,$的意思是以什么结尾,这样就严格限制了必须输入正确的后缀才可以进入网址
二、无名有名分组
分组给某一段正则表达式用小括号括起来,无名和有名不能结合使用,但是无名和有名可以自己多次使用。
# 无名分组会将括号内匹配到的内容当做 位置参数 传递给后面的视图函数test(request,args)
url(r'^test/(\d+)/', views.test)
# 括号就是正则里面的分组,\d 是只要是数字就行,+ 代表的是一到无穷大个, ?是零或者一个,* 是0到无穷大个,正则默认是贪婪匹配。
然后你在url输入http://127.0.0.1:8000/test/111222/
后端的args参数就会接收test后面数字
################################# --分割线-- ##################################
# 有名分组会将括号内匹配到的内容当做 关键字参数 传递给后面的视图函数testadd(request,month)
url(r'^testadd/(?P<month>\d+)/', views.testadd),
# ?P<> 尖括号里面写什么别名就是什么,并且会被当做关键字参数传给后面的视图函数。
url输入http://127.0.0.1:8000/testadd/123/
后端的month就接收了testadd后面的数字
################################# --分割线-- ##################################
# # 可以多次使用,但无名和有名不能一起混用。如下,两个有名参数使用
url(r'^testadd/(?P<month>\d+)/(?P<year>\d+)/', views.testadd),
# 后端视图函数需要testadd(request, month, year)两个参数接收
三、反向解析
现在,有十个app,每个都有一千万个a标签,都可以访问到你的 testadd,然后你的产品经理说,我想要改一下 urls 里面的 testadd ,把它改成 test_add,你只用改一下就好了,然后所有的 a 标签,全都访问不到了,这个时候难道要手动去改a标签的 href吗?
# 当然不可能,这时候就要用到反向解析了。
urlpatterns = [
url(r'^test_add/', views.testadd,name='xxx')
]
只用在后面追加上一个 name ,也就是他的别名,然后在前端页面中的 a 标签里的 href 之中,不要直接写url了,改写成如下。这里的url将会动态的跟随你 urls 里面的配置更改而更改。
<a href="{% url 'xxx' %}">222</a>
前端会用到,那么后端也会有用到,比如当你在重定向的时候, redirect 里面就要写url,这时候不一样,你要首先导入一个reverse模块,跟小白必会三板斧一样,都是从django.shortcuts里导入的。
from django.shortcuts import render,HttpResponse,redirect,reverse
def index(request):
url = reverse('xxx') # 先用 reverse 反向解析出url ,然后把url放进去就好了。
return redirect(url)
四、无名有名分组反向解析
上一个我们说的是普通的urls反向解析,如果urls里带有分组该怎么做
urlpatterns = [
url(r'^test_add/(\d+)/', views.testadd,name='xxx')
]
"""
xxxxxxxxxx <a href="{% url 'xxx' %}">222</a>
url = reverse('xxx')
就像这样子,如果用普通的反向解析是会报错的,报错信息会要求要求你给他一个参数。
"""
1、无名分组反向解析
# 前端
<a href="{% url 'xxx' 123 %}">222</a>
# 后端
reverse('xxx', args=(1,))
"""
在后面给一个数字参数,这个数字一般是数据的主键值
"""
2、有名分组反向解析
url(r'^testadd/(?P<year>\d+)/', views.testadd,name='xxx'),
# 前端解析
方式一、
<a href="{% url 'xxx' 1 %}">222</a>
方式二、
<a href="{% url 'xxx' year=1 %}">222</a>
# 后端解析
方式一、
url = reverse('xxx',args=(1,))
方式二、
url = reverse('xxx',kwargs={'year':123})
# 不用浪费脑容量去记这种方式了,用第一种就好了
五、路由分发
Django里面的每一个应用可以有自己的templates文件夹,urls.py,static文件夹,
正是基于上述特点,Django能够非常好的做到分组开发(每个人只写自己开发的应用)比如说作为开发组组长,手底下的员工分别开发好自己的应用,等全部开发完了,组长只需要将手下开发的应用全部拿走放在一个新的Django项目里,在settings里面注册所有的应用,然后利用路由分发的特点将所有的应用整合在一起。
比如说我有两个应用,一个APP01和一个APP02,两个项目都有登录功能,而且都叫login,这时候怎么让url知道是不同的应用下的登录功能。
这时候就不能用项目下的urls文件了,我们应该再每个APP文件夹下面创建APP的urls文件,APP下的子路由写法与之前的总路由一致
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'^login/', views.login),
url(r'^reg/', views.reg),
url(r'^userlist/', views.userlist),
url(r'^edit_user/', views.edit_user),
url(r'^del_user/', views.del_user),
]
然后我们再在项目文件夹下的urls写总路由
from app01 import urls as app01_urls
from app02 import urls as app02_urls
from django.conf.urls import url,include
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^app01/',include(app01_urls)),
url(r'^app02/',include(app02_urls))
]
'''
这样写之后,接下来你只需要在浏览器里面请求 “127.0.0.1:8080/app01/login/"访问到app01里面的login了,改成app02就能访问到app02的login。
但这样也有个问题,假如有很多应用怎么办,APP01、APP02.....APP100,难道要导入一百个吗,所以我们又有一种优化版本,用字符串来就可以了,省去了导入这些语句
'''
from django.conf.urls import url,include
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^app01/',include('app01.urls ')),
url(r'^app02/',include('app02.urls'))
]
六、其他了解性质内容
伪静态页面
将动态网页假装成是静态的
这样做的目的是为了提高搜索引擎的SEO查询优先级
搜索在收录网站的时候,会优先收录看上去像是静态文件的资源
比如在你的后面加一个.html伪装成静态文件,但其实你根本不是静态文件
但是无论你怎么使用伪静态进行优化,你也干不过RMB玩家
虚拟环境
通常针对不同的项目 只会安装该项目所用的模块 用不到的一概不装
不同的项目有专门的解释器环境与之对应
每创建一个虚拟环境 就类似于重新下载了一个纯净的python解释器
虚拟环境不要创建太多个
django版本区别
django1.x
django2.x
区别1:
urls.py中1.x用的是url,而2.x用的是path
并且2.x中的path第一个不支持正则表达式,写什么就匹配什么
如果你觉得不好用,2.x里面还有re_path 这个re_path就是你1.x里面的url
名称空间
多个应用在反向解析的时候出现了别名冲突的情况
django是无法做到一一对应的>>>名称空间
url(r'^app01/',include('app01.urls',namespace='app01')),
url(r'^app02/',include('app02.urls',namespace='app02')),
reverse('app01:index_view')
reverse('app02:index_view')
{% url 'app01:index_view' %}
{% url 'app02:index_view' %}
# 名称空间其实也可以不需要使用
只需要确保多个应用之间别名也不冲突的情况
eg:起别名的时候加上应用名前缀

浙公网安备 33010602011771号