概述
URL配置就像Django所支撑网站的目录
本质:URL与视图函数的映射表
Django2.0
from django.urls import path
url 换成了 path
基本格式
from django.conf.urls import url urlpatterns = [ url(正则表达式, views视图函数,参数,别名), ]
正则表达式: 一个正则表达式字符串
views视图函数: 一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
参数: 可选的要传递给视图函数的默认参数(字典形式)
别名: 一个可选的name参数
通过URL给视图函数传参
分组匹配和分组命名匹配, 一个正则规则里只能选一个
通过?传值
<a href="/del_publisher/?id={{ publisher.id }}" class="btn btn-danger">删除</a>
取值
request.GET.get("id", None)
def del_publisher(request): print(request.GET) del_id = request.GET.get("id", None) # 获取到用户要删除的数据的ID if del_id: del_obj = models.Publisher.objects.get(id=del_id) # 找到要删除的那条数据 del_obj.delete() # 删除找到的那条数据 return redirect("/publisher_list/") # 返回到出版社列表的页面 else: return HttpResponse("找不到要删除的数据")
分组匹配(按位置传)
url(r'^test30/([a-zA-Z]+)/(d+)/$', views.test20)
视图函数里按照位置接收
def test20(request, name, id): # name是第一个分组, id是第二个分组 return HttpResponse("name:{} id:{}".format(name, id))
分组命名匹配
url(r'^test20/(?P<name>[a-zA-Z]+)/(?P<id>d+)/$', views.test20)
视图函数里按照关键字接收
def test20(request, name, id): # name是第一个分组, id是第二个分组(这里的name,id反过来写也无所谓) return HttpResponse("name:{} id:{}".format(name, id))
视图函数中指定默认值
# urls.py中 from django.conf.urls import url from . import views urlpatterns = [ url(r'^blog/$', views.page), # 当匹配到这个URL的时候,去做默认值的操作 url(r'^blog/page(?P<num>[0-9]+)/$', views.page), # 当匹配到这个URL的时候,去做获取的到num相关的操作 ] # views.py中,可以为num指定默认值 def page(request, num="1"): pass
通过对应关系给视图函数传参
url(r'^test40/([a-zA-Z]+)/(d+)/$', views.test40, {"age": 998})
视图函数里按照关键字接收
def test40(request, name, id, age): # name id 是按照分组传进来的 age 是通过对应关系传进来的 return HttpResponse("name:{} id:{} age:{}".format(name, id, age))
命名URL和URL反向解析
本质上就是给url匹配模式起【别名】,然后url跳转时(a标签/重定向)用过别名拿到具体的URL路径
1, 不带参数版本
url(r'^home', views.home, name='home'), # 给我的url匹配模式起名为 home
在模板里引用
{% url 'home' %}
在views视图里引用
from django.urls import reverse reverse("index")
2, 带参数版本
url(r'^index/(d*)', views.index, name='index'), # 给我的url匹配模式起名为index
在模板里引用
{% url 'index' '实参1' '实参2' %}
在views视图里引用
from django.urls import reverse # 按位置传的参数 reverse("index", args=("实参1", "实参2", ...)) # 按关键字传的参数 reverse("index", kwargs={"形参1": "实参1", "形参2": "实参2", "形参3": "实参3"}, ...)
分级路由与命令空间
分级路由
一个Django 项目里面有多个APP目录大家共有一个 url容易造成混淆,于是路由分发让每个APP的拥有了自己单独的url;
project中的urls.py
from django.conf.urls import url, include from app01 import urls as app01_urls from app02 import urls as app02_urls urlpatterns = [ url(r'^app01/', include(app01_urls)), url(r'^app02/', include(app02_urls)), ]
命名空间
即使不同的APP使用相同的URL【别名】,URL的命名空间模式也可以让你唯一反转命名的URL。
例子
project中的urls.py
from django.conf.urls import url, include from app01 import urls as app01_urls from app02 import urls as app02_urls urlpatterns = [ url(r'^app01/', include(app01_urls, namespace='app01')), url(r'^app02/', include(app02_urls, namespace='app02')), ]
app01中的urls.py
from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^home/', views.home, name='home'), ]
app02中的urls.py
from django.conf.urls import url from app02 import views urlpatterns = [ url(r'^home/', views.home, name='home'), ]
现在,我的两个app中 url名称重复了,我反转URL的时候就可以通过命名空间的名称得到我当前的URL。
语法: '命名空间名称:URL名称'
模板中使用
<a href="{% url 'app02:home' %}">动态版去app02主页</a>
views中的函数中使用
from django.shortcuts import redirect from django.urls import reverse def test11(request): v = reverse('app01:home') # 先通过反向解析 return redirect(v) # 再跳转
from django.urls import reverse 1, 按位置传的参数 reverse("app01:home", args=("实参1", "实参2", ...)) 2, 按关键字传的参数 reverse("app01:home", kwargs={"形参1": "实参1", "形参2": "实参2", "形参3": "实参3"}, ...)