一、Django——路由层
Django——路由层相关(urls.py)
一、Django请求生命周期流程图

该图是我们学习的django的流程 也是后期复习django重要的手段
学习路线:
1、路由层
2、视图层
3、模板层
4、模型层

二、路由匹配
路由匹配的原则:
从上往下正则表达式能够匹配到内容就算匹配成功会立刻执行后面的视图函数并且结束整个路由匹配过程
----------------------------------"urls.py"----------------------------------
urlpatterns = [
url(正则表达式,函数或者类型地址,name=None),
url(正则表达式,函数或者类型地址,name=None)
]
url的三个参数:
1、正则表达式(正则表达式也可以加括号,然后起别名)
2、函数或者类型地址
3、name反向解析的别名
案例:
urlpatterns = [
url(r'^admin/', admin.site.urls),
# 首页 (^$就是什么都不输,为空)
url(r'^$',views.home),
url(r'^test/$',views.test),
url(r'^testadd/$',views.testadd),
# 404页面 (放在最后,什么都没匹配上的话,那就默认返回404页面)
url(r'',views.error)
]
注意:
"""
当web浏览器访问不到路径,匹配不上的时候,Django会让浏览器的url最后一个加上"/",再重新匹配一次
自动加"/"是Django的功能,不是web浏览器
在settings.py内,添加下面的参数即可关
APPEND_SLASH = False # 默认是True,改了False就是Django不自动加/
"""
三、无名和有名分组
分组:
定义:url的正则匹配项,将部分正则使用括号括起来
有名无名:
定义:在括号内的正则,起一个别名
# 注意:不是url的第三个参数name
1、有名分组
定义:被'括号包含'的url的正则匹配项,起一个别名了
功能:会把'分组匹培到的内容'将'键值对'的形式传给对应的函数
正则案例:给[0-9]{4}正则项起别名:
(?P<year>[0-9]{4}) # 注意:是大写的P
有名分组例:
# urls.py
url(r'^hasname/(?P<year>[0-9]{4})',views.hasname)
#views.py
def hasname(request,**kwargs):
print(kwargs)
return HttpResponse("这是hasname")
流程1:
当输入 "127.0.0.1/hasname/1234/" ,urls路由匹配上hasname函数
流程2:
会把 year=1234 传给views.py的hasname的**kwargs
"""
在路由匹配如果将某部分正则使用括号括起来了
那么该部分正则匹配到的内容会当做关键字参数传递给后面的视图函数
"""
2、无名分组
定义:被'括号包含'的url的正则匹配项,没有起命名
功能:会把'分组匹培到的内容'按'位置参数'的形式传给对应的函数
无名分组例:
# urls.py
url(r'^noname/([0-9]{4})/',views.noname)
#views.py
def noname(request,*args):
print(args)
return HttpResponse("这是noname")
流程1:
当输入 "127.0.0.1/test/1234/" ,urls路由匹配上noname函数
流程2:
会把 1234 传给views.py的noname的*args
"""
在路由匹配如果将某部分正则使用括号括起来了
那么该部分正则匹配到的内容会当做位置参数传递给后面的视图函数
"""
重要:
重要:
1、能否混用?
不能混用
url(r'^index/(\d+)/(?P<xxx>\d+)/',views.index)
2、单个情况下可以重复使用
# 注意在views接受的时候要用*args和**kwargs接收。
url(r'^index/(\d+)/(\d+)/(\d+)/',views.index)
url(r'^index/(?P<yyy>\d+)/(?P<xxx>\d+)/',views.index)
四、反向解析
1.在路由层书写正则与函数名的时候 在后面加一个'唯一标识'
url(r'^login/',views.login,name='my_login')
2.前端反向解析
{% url 'my_login' %}
3.后端反向解析
from django.shortcuts import reverse
_url = reverse('my_login')
"""
通过标记解析出一个结果 该结果可以访问到标记所在的那一行地址
"""
反向解析案例:
1、需求:
# 当某个网址不是静态资源网址,会随着业务需求变更的时候,最好不要写死,利于后期维护
1、要求'127.0.0.1:8000/home/'网页上有跳转到'127.0.0.1:8000/func/'网页的标签
2、这个'127.0.0.1:8000/func/'的'/func/'不能写死
3、后期只要改url()的正则项,而不用再改html文件和views文件(也即网址更改,但是访问的内容不改)
2、准备
----------------------------'settings.py'-----------------------------------
urlpatterns = [
url(r'^home/',views.home),
url(r'^func/',views.func,name="my_func") # 起了个别名my_func
]
----------------------------'views.py'-----------------------------------
from django.shortcuts import render,reverse
def home(request):
return render(request,"home.html")
def func(request):
print(reverse(viewname="my_func")) #反向解析名
return render(request, "func.html")
----------------------------'home.html'-----------------------------------
<body>
<a href="{% url 'my_func' %}">111</a>
<a href="{% url 'my_func' %}">222</a>
<a href="{% url 'my_func' %}">333</a>
<a href="{% url 'my_func' %}">444</a>
<a href="{% url 'my_func' %}">555</a>
<a href="{% url 'my_func' %}">666</a>
</body>
----------------------------'func.html'-----------------------------------
<body>
<h1>这是func.html文件页面</h1>
</body>
3、测试
1、打开web浏览器127.0.0.1:8000/home/
前端:①点击标签,正常跳转到127.0.0.1:8000/func/
②访问到的是func.html文件
后端:pycharm打印出"/func/"
2、只修改url()的正则项
urlpatterns = [
url(r'^home/',views.home),
url(r'^xxx/',views.func,name="my_func") # 将/func/改为/xxx/
]
3、打开web浏览器127.0.0.1:8000/home/
前端:①点击标签跳转到127.0.0.1:8000/xxx/
②依然访问func.html文件
后端:pycharm打印出"/xxx/"
结果
反向解析简单来说:
网页地址不是写死的,
而是通过'settings.py'的'url的第三个别名项',
让前端和后端通过别名查找'url的第一个正则匹配项'
五、无名有名反向解析
在理解了Django的:
1、分组
2、有名、无名
3、反向解析
可以继续往下结合应用
无名、有名分组、反向解析
# 无名分组的反向解析
url(r'^login/(\d+)/',views.login,name='my_login')
后端
_url = reverse('my_login',args=(111,))
print(_url) # /login/111/
前端
{% url 'my_login' 1 %}
# 有名分组的反向解析
url(r'^login1/(?P<xxx>\d+)/',views.login1,name='my_login1')
后端
_url = reverse('my_login',kwargs={'xxx':123})
print(_url) # /login/123/
前端
{% url 'my_login' xxx=1 %}
"""其实无名有名反向解析可以使用通用的方式"""
都可以使用无名分组的反向解析
测验
1.使用无名有名分组及反向解析完成ORM操作的数据增删改查(改 删)
2.整理今日内容及博客
3.使用虚拟环境下载一个django3.X版本备用
六、路由分发
当django项目特别庞大的时候 如果所有的路由匹配都写在项目的总路由中会导致总路由过于复杂不利于维护 此时可以将路由做拆分
"""
django支持所有的应用都可以拥有自己的
urls.py
templates文件夹
static文件夹
也就意味着多人协同开发变得更加的简单了
"""
如何将多个单独的app组织到一起 >>> 路由分发
总路由
from app01 import urls as app01_urls
from app02 import urls as app02_urls
from django.conf.urls import url,include
# 路由分发
url(r'^app01/',include(app01_urls)),
url(r'^app02/',include(app02_urls)),
子路由
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'^index/',views.index)
]
子路由
from django.conf.urls import url
from app02 import views
urlpatterns = [
url(r'^index/',views.index)
]
# 更加简便的写法
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls')),
七、名称空间(了解)
# 当多个app中出现了相同的别名 那么使用反向解析无法自动识别
总路由
# 名称空间
url(r'^app01/',include('app01.urls',namespace='app01')),
url(r'^app02/',include('app02.urls',namespace='app02')),
反向解析
reverse('app01:my_index')
reverse('app02:my_index')
{% url 'app01:my_index' %}
{% url 'app02:my_index' %}
"""
名称空间其实也可以不用 只需要确保不同的app下别名不冲突即可
如何不冲突
可以在起别名的时候加上应用名前缀
app01_my_index
app02_my_index
"""
八、伪静态(了解)
静态页面
数据写死的 不怎么改变的
伪静态页面
看似是文件其实是动态网页 这么做事为了提高网站被搜索引擎收录的概率
将路径后缀改为.html形式即可
九、虚拟环境(了解)
虚拟环境能够实现针对不同的项目配备专属的编程环境
创建虚拟环境相当于重新下载了一个新的解释器
虚拟环境的唯一表示是venv文件夹