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),
相关推荐
zi__you2 分钟前
【Python网络爬虫笔记】2-HTTP协议中网络爬虫需要的请求头和响应头内容
笔记·爬虫·python
Smile灬凉城66610 分钟前
CTF之WEB(sqlmap tamper 参数)
python·安全·sqlmap
栗子~~11 分钟前
GaussDB(类似PostgreSQL)常用命令和注意事项
数据库·postgresql·gaussdb
allanGold12 分钟前
【sqlcipher】pc端sqflite使用过程中遇到的问题
数据库·sqflite
小人物之辈12 分钟前
MySQL 查询 执行顺序
数据库·mysql
莫叫石榴姐13 分钟前
SQL进阶技巧:非等值连接--单向近距离匹配
大数据·数据库·hive·sql·oracle·数据分析
三天不学习16 分钟前
【连接池】.NET开源 ORM 框架 SqlSugar 系列
数据库·orm·sqlsugar
zxrhhm16 分钟前
PostgreSQL 9.4 引入的一个特性生成列(Generated Columns)
数据库·postgresql
破无差17 分钟前
SQL Server第五章-聚合函数在查询中的使用(头歌)答案代码
数据库·sql
y250833 分钟前
《String类》
开发语言·python