[Django]:url地址匹配问题
随着Django的更新,最新版本的2.x与旧版本1.x在某些⽅⾯有⼀些不同,在这⽚博客中我们会提⼀下,在url地址匹配中的2.x版本与1.x版本的不同之处。
⼀.路由基础
在urls模块中的 urlpatterns列表中存放着正则路径,视图函数地址,默认关键字参数(可选),路由别名(可选)。
1.功能函数不需要传参
# url(r'^login$', views.login) 只能匹配login,不能匹配index/
# url(r'^login/$', views.login)能匹配login/,也能匹配login(先拿index匹配,如果失败,会添加/再次匹配)
在settings中添加APPEND_SLASH = False 会导致Django不会⾃动添加/,也可以将settings中将'django.middlewaremon.CommonMiddleware'
注释掉
2.功能函数需要传参
#url(r'^login/$', views.login, {'num': 88888}) 此处为关键字参数
#功能函数为如下:
def login(request,num):
pass
有名⽆名分组
在我们平时浏览⽹页的时候会发现在⼀些⽹址后后⾯后添加着⼀些数字(我们将这些页⾯称之为⼦页⾯,这些数字可能是为功能函数提供某个参数,或者是数据库中的某个数据的⼀个数据),例如:x/1/2,那么这种句⼦的匹配应该如何匹配呢,这就需要使⽤到有名⽆名分组了。
⽆名分组:
url(r'^login/(\d+)$',views.login)
#功能函数为:
def login(request,var):
print(var)
return render(request,'login.html')
有名分组:
url(r'^login/(?P<num>(\d+))$',views.login)
#功能函数为:
def login(request,num):
print(num)
return render(request,'login.html')
#注意:有名分组中的num名字必须与函数中的参数名对应,否则会参数错误
有名与⽆名分组均可以写对个值,如:
⽆名分组:
url(r'^login/(\d+)/(\d+)$',views.login)
#功能函数为:
def login(request,var,num):
print(var,num)
return render(request,'login.html')
#最终对应的url如下:127.0.0.1:8802/10/20,有名分组与其⼀致,不过在有名分组中多个参数,在功能函数中只按名字对应,位置前后不会影响
值的顺序。
多app共存的路由分配
多个app创建过程
'''
1.创建多个应⽤:django-admin startapp app_name | python3 manage.py startapp app_name | Tools⼯具
2.在settings.py中配置INSTALLED_APPS,添加新建的应⽤:'app_name.apps.App_nameConfig'
'''
在⼀个Django中会出现多个功能模块,那么每个app都对应着⼀个views模块,在⾥⾯写着各⾃的功能代码,有时两个功能模块可能会出现两个名字⼀致的函数,但是他们实现的功能却是不⼀致的,如何解决这个问题呢?
import app01.views as app01_views
import app02.views as app02_views
urlpatterns = [
url(r'^app01/test/$', st),
url(r'^app02/test/$', st),
]
#在导⼊模块时,将每个不同功能模块的views模块起⼀个不同的名字,并且url地址也要加上对应的功能模块名,⼀⼀对应,即使⽤⽅便,也不会出现多app的路由冲突。
模板冲突问题
'''
⽅法1:在对应应⽤下建⽴⾃⼰的templates,再在templates下建⽴与应⽤名同名的⽂件夹,模板⽂件放在应⽤名同名的⽂件夹下
⽅法2:在项⽬根⽬录下的templates中建⽴每⼀个应⽤同名的⽂件夹,每个应⽤的模板⽂件放在⾃⼰应⽤名⽂件夹下
使⽤:render(request, 'app_name/test.html')
'''
路由分发
当我们不对项⽬中的urls模块进⾏处理,会导致随着项⽬的进度,在urls中堆积的代码会越来越多,
不便于我们对于到代码的管理,因此我们使⽤路由分发解决这个问题。
'''
# 分担总路由的代码压⼒
1.在每⼀个应⽤中建⽴⾃⾝的urls.py⽂件,语法同主路由
2.在主路由进⾏分发
f.urls import include
urlpatterns = [
url(r'^app01/', include('app01.urls')),
url(r'^app02/', include('app02.urls')),
]
# 注:主路由分发⼀定不能使⽤$正则语法
'''
路由别名
'''
1.有些路由会被⼤量访问(直接访问、间接访问)
2.这些路由可能后期还会发⽣变化
3.可以给路由设置别名,通过别名访问:<a href="{% url '路由别名' '传⼊有名⽆名分组所需参数' %}"></a>
'''
反向解析
'''
from django.shortcuts import reverse
在视图函数中通过reverse⽅法反向解析出真实的路径
# 1.不带分组:url(r'可能会变的真实路由', 视图函数, name='路由别名')
url = reverse('路由别名')
# 2.⽆名分组:url(r'可能会变的真实路由(带⽆名分组)', 视图函数, name='路由别名')
url = reverse('路由别名', args=(给⽆名分组赋值))
# 3.有名分组:url(r'可能会变的真实路由(带有名分组)', 视图函数, name='路由别名')
url = reverse('路由别名', kwargs={给有名分组赋值,key就是有名分组名})
'''
名称空间
'''
主路由:
f.urls import include
urlpatterns = [
url(r'^app01/', include('app01.urls', namespace='app01')),
url(r'^app02/', include('app02.urls', namespace='app02')),
]
app01应⽤下路由
f.urls import url
from app01 import views
urlpatterns = [django admin 自定义页面
url(r'^test/', st, name='test')
]
app02应⽤下路由
f.urls import url
from app02 import views
urlpatterns = [
url(r'^test/', st, name='test')
]
前端页⾯反向解析:{% url 'app01:test' %} | {% url 'app02:test' %}
视图函数reverse⽅法:url = reverse('app01:test') | url = reverse('app02:test')
'''
2.x新特性
'''
from django.urls import path, re_path # 2.x版本
f.urls import url # 1.x版本,向下兼容,但不建议使⽤
urlpatterns = [
path('admin/', admin.site.urls),
]
# 1. 2.x版本re_path的使⽤⽅式同1.x版本url
# 2. path写的是绝对字符串,请求地址必须与路由地址完全匹配
# 3. path拥有五个转换器:
-- str:匹配除路径分隔符(/)外的字符串,默认
-- int:匹配⾃然数
-- slug:匹配字母、数字、横杠及下划线组成的字符串
-- uuid:匹配uuid形式的数据
-
- path:匹配任何字符串,包括路径分隔符(/) (不能⽤?)
'''
⾃定义转换器
'''
1. 在⾃定义⽂件中⾃定义类,采⽤固定格式作为conventer
eg:在app应⽤下的conventer⽂件中建⽴CVT185Phone类
class CVT185Phone:
regex = '185\d{8}'
def to_python(self, value):
return int(value)
def to_url(self, value):
return '%11d' % value
2. 在路由中注册⾃定义转换器
from django.urls import register_converter
from app import view, conventer
register_converter(conventer.CVT185Phone, 'phone185') # ⾃定义转换器名:phone185 urlpatterns = [
path('test/<phone185:phone>/', st, name='test_phone'),
]
# 可以匹配138的电话,to_python决定了类型为int,to_url服务于反向解析(反向解析需要使⽤字符串) # url = reverse('test_phone', kwargs={'phone': 8888}) # 反向解析传⼊不满11位,会被格式化位11位'''
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论