Django进阶-路由系统

概述

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("找不到要删除的数据")
views.py

分组匹配(按位置传)

url(r'^test30/([a-zA-Z]+)/(\d+)/$', views.test20)

视图函数里按照位置接收

def test20(request, name, id):        # name是第一个分组, id是第二个分组
    return HttpResponse("name:{} id:{}".format(name, id))
views.py

分组命名匹配

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))
views.py

视图函数中指定默认值

# 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))
views.py

命名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)                  # 再跳转 
views.py
from django.urls import reverse

1, 按位置传的参数
reverse("app01:home", args=("实参1", "实参2", ...))

2, 按关键字传的参数
reverse("app01:home", kwargs={"形参1": "实参1", "形参2": "实参2", "形参3": "实参3"}, ...)
带参数的写法

 

posted @ 2018-10-01 20:46  孙昌恒  阅读(195)  评论(0编辑  收藏  举报