02_Django路由Router

二、Django路由Router

在实际开发过程中,一个Django 项目会包含很多的 app ,这时候如果我们只在主路由里进行配置就会显得杂乱无章,所以通常会在每个 app 里,创建各自的urls.py路由模块,然后从根路由出发,将 app 所属的 url 请求,全部转发到相应的 urls.py 模块中。而这个从主路由转发到各个应用路由的过程叫做路由的分发

re_path正则路由的写法
python 复制代码
# re_path正则写法 ()表示正则分组为一个参数 (?P<参数名>regex)
re_path(r'^user_view_ab/(?P<a>\d+)/(?P<b>\d+)/$', user_view_ab, name="user_view_ab")

这样就是匹配user_view_ab/1/2等数字参数

路由匹配
python 复制代码
# 使用url给视图函数传参数
path('index/', index)
path('detail/<int:id>/', detail)


# 给url取别名,那么在使用此url的地方(例如页面模板反向解析)可以使用别名。比如:
path('index/',index,name='index')
path('detail/<int:id>/', detail, name='detail')

根据路由的name属性,获取路由url
reverse('index') => 路由'index/'
反向解析

Django路由反向解析是一个非常重要的功能,它可以让我们在代码中使用路由别名替代URL路径,在修改URL时避免代码中的硬编码依赖,同时也可以提高可读性和可维护性。

python 复制代码
# 在视图函数中,反向解析url:
from django.shortcuts import render,redirect,reverse
def buy(request):
	return redirect(reverse('index'))
	return redirect(reverse('detail',args=[2]))
	return redirect(reverse('detail',kwargs={"id":2}))

#在templates中,使用别名:
	{% url 'detail' stu.id %}
    
# 使用命名空间:
# 指定命令空间后,使用反向解析时需要加上命名空间,比如:
#	1.在视图函数中:
	return redirect(reverse('App:index'))
#	2.在templates中:
	{% url 'App:index'%}
页面之间相互跳转(通过html)
  1. 在根目录下的urls.py添加如下代码
python 复制代码
from django.contrib import admin
from django.urls import include, path
from App.views import *
urlpatterns = [
    # 使用子路由: 
    path("user/", include("App.urls")),

    # 使用子路由: 使用命名空间
    path("user/", include(("App.urls","App"), namespace="App")),

    path('admin/', admin.site.urls),
]
  1. App/urls.py子路由文件
python 复制代码
from tkinter.font import names
from django.urls import path
from App.views import *
urlpatterns = [
    # 首页
    path('index/', index, name='index'),
    # 用户列表
    path('user_list/', user_list, name='user_list'),
]
  1. 定义视图函数user_list.html文件
python 复制代码
# 用户列表
def user_list(request):
    return render(request, 'user_list.html')
  1. 在想要添加跳转链接的页面(这里只使用后端的Django跳转方式,不使用前端超链接)添加代码
django 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Index</title>
  </head>
  <body>
    <h2>首页</h2>
    <hr />
    {% comment %} url路由来跳转 {% endcomment %}
    <a href="/user/user_list/">url路由跳转: 进入用户列表</a>
    <hr />

    {% comment %} 反向解析来跳转 {% endcomment %}
    <a href="{% url 'user_list' %}">反向解析跳转: 进入用户列表</a>
    user_list是路由路径的name值
      url 是Django的模板,用于生成url
    <hr />

    {% comment %} 带命名空间的反向解析 {% endcomment %}
    <a href="{% url 'App:user_list' %}">带命名空间的反向解析: 进入用户列表</a>
  </body>
</html>
  • url路由跳转方式: 链接路径为 127.0.0.1:8000后面的内容
  • 反向解析来跳转: 反向解析就是从 html页面(点击) -> 找到路由 -> 找到视图函数(user_list是路由路径的name值)
  • 带命名空间的反向解析: 命名空间就是根/urls.py文件include方法中指定的namespace,命名空间就是为了使不同的应用之间可以使用相同的子路由路径名(例如上面的user_list)
路由传参(单个参数)

App的子路由中新增以下路由规则

python 复制代码
# 详情页 <> 号内为参数传给user_detail视图函数
path('user_detail/<int:uid>/', user_detail, name='user_detail'),

定义视图函数user_detail

python 复制代码
# 用户列表
def user_list(request):
    # 获取所有用户数据
    users = UserModel.objects.all()
    return render(request, 'user_list.html',{"users":users})
def user_detail(request,uid): # uid从路由参数中获取
    # print("uid",uid)
    # 获取单个用户数据
    user = UserModel.objects.get(pk=uid)    # pk是主键primary key
    return render(request, 'user_detail.html',{"user":user})  # 传递参数到模板中

在user_list.html文件中接收user_list传过来的users参数,遍历(利用模板语法添加li>a标签)

django 复制代码
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>用户列表</title>
        <style>
            a {
                text-decoration: none;
            }
        </style>
    </head>
    <body>
        <h2>用户列表</h2>
        <hr />
        <ul>
            {% for user in users %} {% comment %} 反向解析 {% endcomment %}
            <li>
                <a href="{%url 'App:user_detail' user.id%}">{{user.name}} - {{user.age}}</a>
            </li>
            {% endfor %}
        </ul>
    </body>
</html>

所以,最终生成的a标签变成了<a href="/user/user_detail/1/">张三 - 19</a>

整个过程就是按顺序发生

  • 首先用户访问user/user_list.html界面,程序调用视图函数获取所有用户列表并传参
  • user_list函数中,程序渲染本地的user_list.html返回,在渲染的过程中,将uset_list()中获取的用户列表逐个渲染成具体的链接
  • 这是对模板语法的解释
  • url 代表当前界面的url, App:user_detail表示到根路由path("user/", include(("App.urls","App"), namespace="App"))中在逐层(include(("App.urls","App"),从应用App的urls.py子路由文件)找到名为user_detail的路由项
  • 找到如下所示path('user_detail/<int:uid>/', user_detail, name='user_detail')
  • 然后user.id就是把id属性传给路由参数,相对于变成``path('user_detail/user.id/', user_detail, name='user_detail')`
路由参数支持的类型

Django支持多种类型的路由参数,常见的有:

  1. int :接收整数,如 <int:user_id>
  2. str :接收字符串,如 <str:username>
  3. slug :接收短横线连接的字符串,如 <slug:slug>
  4. uuid :接收UUID,如 <uuid:uuid>
  5. path :接收包含斜杠的字符串,如 <path:subpath>
路由传参(多参数)

视图函数

python 复制代码
def user_view_ab(request,a,b):
    return HttpResponse(f"a={a},b={b}")

子路由

python 复制代码
# 带参数的视图函数,注意,参数的名字必须和视图函数中参数的名字一致
path("user_view_ab/<int:a>/<int:b>/", user_view_ab, name="user_view_ab")

注意!!! 参数名称要对应

重定向redirect函数

在视图函数中,可以重定向到别的网页或者路径

python 复制代码
path('user_detail/<int:a>/',user_detail,name='userdetail'),def user_detail(a):
    return HttpResponse("user_detail")
# 重定向
def my_redirect(request):
    return redirect('http://www.baidu.com')

def my_redirect2(request):
    return redirect('/user/user_list/')

def my_redirect3(request):
    # reverse反向解析(根据路由name属性找到对应url)
    return redirect(reverse('user_list')) # 相当于  return redirect(/user/user_list/)
	return redirect(reverse('App:userdetail', args=(1,))) # 传参给path('user_detail/<int:a>/',user_detail,name='userdetail'),args=元组或列表,kawrgs=字典
	return redirect(reverse('App:userdetail', kwargs={'a':2}))

在子路由中增加重定向部分

python 复制代码
# 用户列表(原有)
path('user_list/', user_list, name='user_list'),
path('user_detail/<int:a>/',user_detail,name='userdetail'),
# 重定向
path('myredirect/', my_redirect),
path('myredirect2/', my_redirect2),
path('myredirect3/', my_redirect3),
相关推荐
心平愈三千疾14 分钟前
通俗理解JVM细节-面试篇
java·jvm·数据库·面试
费弗里44 分钟前
Python全栈应用开发利器Dash 3.x新版本介绍(1)
python·dash
李少兄9 天前
解决OSS存储桶未创建导致的XML错误
xml·开发语言·python
就叫飞六吧9 天前
基于keepalived、vip实现高可用nginx (centos)
python·nginx·centos
Vertira9 天前
PyTorch中的permute, transpose, view, reshape和flatten函数详解(已解决)
人工智能·pytorch·python
学Linux的语莫9 天前
python基础语法
开发语言·python
我科绝伦(Huanhuan Zhou)9 天前
Oracle|Oracle SQL*Plus 配置上下翻页功能
数据库·sql·oracle
匿名的魔术师9 天前
实验问题记录:PyTorch Tensor 也会出现 a = b 赋值后,修改 a 会影响 b 的情况
人工智能·pytorch·python
Cachel wood9 天前
Spark教程6:Spark 底层执行原理详解
大数据·数据库·分布式·计算机网络·spark
Ven%9 天前
PyTorch 张量(Tensors)全面指南:从基础到实战
人工智能·pytorch·python