目录
-路由匹配
-无有名分组
--无名分组
--有名分组
-反向解析
--含义
--实现
--无有名分组反向解析
---无名分组反向解析
---有名分组反向解析
-路由分发
--含义
--实现
-名称空间
-伪静态网页
对django1.x,路由匹配用的是url正则匹配;django2.x和django3.x有直接匹配path和正则匹配re_path两种方式
# django 1.x
urlpatterns = [
url(正则表达式,view视图函数,参数,别名),
]
# django 2.x 和 django 3.x
urlpatterns = [
path(匹配表达式,view视图函数,参数,别名),
]
urlpatterns = [
re_path(正则表达式,view视图函数,参数,别名),
]
路由匹配时,是将urlpatterns列表循环匹配,只要第一个匹配的参数能匹配到,就自动调用视图函数执行而不再继续往下匹配了
我们在浏览器输入url没有加最后一个"/"时也会匹配成功,因为django自动帮你做了重定向,一次匹配不行,就自动后面拼接上"/"再匹配
# 取消django路径下默认给你加/的方法
settings.py
APPEND_SLASH = Flase
在使用正则匹配时,要用^和$限制路径,否则会出现:
from django.urls import re_path
urlpatterns = [
re_path('test/', views.test),
]
# 正则匹配若不限制^和$会导致路径的不专一
.../test/weer 也能匹配到test/路径下的视图函数
.../weer/test/ 也能匹配到test/路径下的视图函数
.../weer/test/abc123 也能匹配到test/路径下的视图函数
# 而使用限制时:re_path('^test/$', views.test())就只能通过.../test/匹配到了
无有名分组利用的是正则匹配,就是将路径中的一些值用参数包起来当做值,可以传入其它地方比如视图函数中使用
将括号内正则表达式的匹配内容当做位置参数传给视图函数,即视图函数多个形参
urls.py
re_path('^test/(\d+)/$', views.test),
views.py
def test(request, num):
print(num)
return HttpResponse('test')
'''
即此时路径需输入test/数字/才能访问到test函数下的内容,
且test函数必须传入一个形参(这是num)来接收输入的数字,
否则会报test() takes 1 positional argument but 2 were given的错。
传入形参num后还能得到用户输入的路径后的数字
'''
将括号内的正则表达式匹配到的内容当做关键字参数(一般是给正则表达式起个别名当做关键字参数)传递给后面的视图函数
urls.py
re_path('^testadd02/(?P\d+)', views.test_add_02),
views.py
def test_add_02(request, number):
print(number)
return HttpResponse('test_add_02')
'''
就是用语法给正则式起个别名分组,作为传入视图函数的形参用来接收
也能获取用户输入的路径后的内容(这是数字)
'''
注:有名无名不能混合使用,但同一个分组下可以多次使用
re_path('^index/(\d+)/(\d+)/', views.index),
re_path('^index/(?P\d+)/(?P\d+)/', views.index),
指通过一些方法得到一个结果,该结果可以直接对应访问url触发视图函数
用途:比如可以实现后端路由路径名改变,导致前端绑定跳转地址无用,减少前端页面一个一个改的繁琐;后端获取到的路径无,重新修改代码获取等…
→先给路由与视图函数起一个别名:
path('hello/', views.hello, name = 'wmq'), # 别名不能冲突!
→反向解析:
前端反向解析:
111
后端反向解析:
from django.shortcuts import reverse
print(reverse('wmq')) # 获取别名wmq对应路径,即:/hello/
就是利用正则匹配方式的路径,给起起个别名,前后端通过别名并传入必要参数(在reverse那传入因有无名分组所需的必要参数即可,若为数字一般为其主键id)来实现访问该路径
# 无名分组反向解析
re_path('^index/(\d+)/$', views.index, name='weer'),
# 前端
{% url 'weer' 666 %} # 传入别名和所需参数
# 后端
def test(request, num):
print(reverse('weer', args=(123,))) # /index/123/
...
# 有名分组反向解析
re_path('^func/(?P\d+)/$', views.fucn, name='weer'),
# 前端
# click me # 了解
click me # 简便写法,掌握
# 后端
# print(reverse('weer', kwargs={'number':666})) # 了解
print(reverse('weer', args=(666, ))) # 简便写法,不用记参数叫什么,掌握
Django的每一个项目都可以有自己的templates文件夹、urls文件夹、static文件夹
正是由于这个特点,Django项目能做到分组开发(每个人写自己的app)
然后由组长通过路由分发实现在一个项目中汇总到总路由中
# 子路由
# app01/urls.py
from django.urls import path
from app01 import views
urlpatterns = [
path('login/', views.login),
]
# app02/urls.py
from django.urls import path
from app02 import views
urlpatterns = [
path('login/', views.login),
]
总路由urls.py
# 方式一
from django.urls import path,include
from app01 import urls as app01_urls # 起别名,防冲突
from app02 import urls as app02_urls
urlpatterns = [
path('admin/', admin.site.urls),
# 路由分发↓
path('app01/', include(app01_urls)), # 只要路由前缀是app01就由app01中的视图函数处理
path('app02/', include(app02_urls)), # 只要路由前缀是app02就由app02中的视图函数处理
]
# 方式二 推荐使用
from django.urls import path,include
import app01
import app02
urlpatterns = [
path('admin/', admin.site.urls),
# 路由分发↓
path('app01/', include('app01.urls')),
path('app02/', include('app02.urls')),
]
各子路由下视图函数名有相同情况下,反向解析不能实现自动识别各应用下的视图函数名,此时需要使用名称空间
# 在总路由中加一个namespace = ' '参数,解析时前后端各自解析
# 总路由
path('app01/', include('app01.urls'), namespace='app01'),
path('app02/', include('app02.urls'), namespace='app02'),
# app01
urlpatterns = [
path('login/', views.login, name='xxx'),
]
# app02
urlpatterns = [
path('login/', views.login, name='xxx'),
]
# 解析 语法:'命名空间名称:URL名称'
path1 = reverse('app01:xxx')
path2 = reverse('app01:xxx')
{% url 'app01:xxx' %}
{% url 'app02:xxx' %}
静态网页:数据是写死的,万年不变 伪静态网页:将一个动态网页伪装成一个静态网页
目的:增大本网页被搜索引擎收录的概率,增大本网站的seo查询力度
(搜索引擎本身是一个巨大的爬虫程序,它知道你是个静态网页后就会优先把你收录起来因为你的内容数据不变嘛,所以下次用户搜索展示的时候就可能会优先展示该网页)
比如把路径后缀加一个.html,看似是一个html静态文件,就实现了粗浅的伪装
但总结:无论我们怎么优化怎么伪装,都干不过RMB玩家
搜索引擎还是会优先展示RMB玩家的内容/网页