Django入门02——Django路由

Django路由详解

一、路由route

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

1.1 路由匹配:

  • 使用url给视图函数传参数
path('index/',index)
path('detail/<int:id>/',detail)
  • 给url取别名,那么在使用此url的地方可以使用别名。比如:
path('index/',index,name='index')
path('detail/<int:id>/',detail,name='detail')

1.2 命名空间

在实际应用中,Django中可能存在多个应用程序,每个应用程序都可能有自己的路由模块,即每一个应用都可以用一个命名空间取定义。为了防止路由冲突,Django提供了命名空间(namespace)的概念。命名空间是一种将路由命名为层次结构的方式,使得在查询路由时可以限定在该命名空间内。

在跟路由中可以设置命名空间:

path('app/',include(('App.urls','App'),namespace='App'))

1.3 反向解析

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

  • 在视图函数中,反向解析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' %}

二、创建路由

2.1 直接使用跟路由

首先要从views.py中导入视图函数,然后写路由user/,映射的视图函数是user()函数
在这里插入图片描述

2.2 创建子路由(include)

每一个应用只能对应一个子路由,如果要创建子路由,则在应用下创建一个新的python文件,命名为urls.py。
要导入include()方法:

from django.urls import path,include

然后在项目目录下的urls.py即跟路由中为应用创建子路由:
在这里插入图片描述
接着我们的子路由就不用再跟路由中定义了,需要在应用的urls.py中定义,如果要访问子路由,首先到跟路由中找到App01,然后再到APP01下的urls.py中查找对应的子路由。
在应用的urls.py中,我们需要定义子路由,就和跟路由中定义跟路由一样。
在这里插入图片描述

2.3 创建子路由(include和命名空间namespace)

path()中第一个参数是应用的路径,include()中的第一个参数是应用的子路由的路径,第二个参数是命名空间namespace,namespace的值最好和应用的名字一致。
在这里插入图片描述

2.4 在应用中创建子路由

在应用中新建一个urls.py,它用于存放该应用的子路由。注意,一个应用只能对应一个子路由文件,即应用目录下只能包含一个urls.py。

子路由的结构与跟路由一样:
如果使用命名空间,则path中需要有3个参数,即比不用namespace需要多写一个参数namespace。
在这里插入图片描述

编写视图函数user():
在这里插入图片描述
编写模板文件user.html:
在这里插入图片描述
路由、视图函数、模板文件都准备好之后,就可以访问。在终端输入命令python manage.py runserver,打开网址127.0.0.1:8000/App01/user
在这里插入图片描述

三、页面跳转——使用反向解析和命名空间

使用前端可以通过超链接实现页面跳转。在后端可以通过Django实现页面跳转,即所有的跳转请求都需要经过后端。

首页index已经创建好了,接下来创建一个用户列表userlist页面:

  • 视图函数:
def user_list(request):
    return render(request,'user_list.html')
  • 路由:
    (使用include)
# 跟路由:
path('App01/',include('App01.urls')),
# 子路由:
path('userlist/',user_list,name='userlist'),

或者(使用include和namespace)

# 跟路由:
path('App01/',include(('App01.urls','App01'),namespace='App01')),
# 子路由:
path('userlist/',user_list,name='userlist'),

注意:这两种使用子路由的方法一次只能使用其中一种。

  • 模板

接下来要实现两个页面的跳转:
(1)通过url路径来实现跳转(超链接)
在index.html中使用超链接跳转到用户列表页面。使用超链接,通过url路由路径实现页面跳转。
在这里插入图片描述
刷新之后的首页页面:
在这里插入图片描述
点击之后,即可跳转到用户列表页面。因为我们点击超链接,对页面发起请求,然后就会查找路由进行匹配,匹配到正确的路由之后访问对应的视图函数user_list,视图函数将网页请求和模板渲染并返回用户列表页面,就实现了从首页跳转到用户列表页面。

(2)反向解析
正常来说,我们访问后台需要在浏览器中有路由地址,有路由地址之后,先匹配路由,再访问视图函数,再进入到模板文件。反向解析就是先到html中找url的name,通过name来匹配url,即通过name找到对应url的路由路径和对应的视图函数,再进入到视图函数中。
在这里插入图片描述
对应的路由描述方式(使用include):
在这里插入图片描述
页面效果:
在这里插入图片描述

(3)带命名空间的反向解析
使用命名空间的好处是,如果在不同应用中有相同的name,那么就可以通过命名空间区分它们,因为一个应用只能对应一个命名空间,一般命名空间的名字与所在应用的名字相同。

注意:方法2和方法3只能用一个,否则会报错。
在这里插入图片描述
对应的路由描述方式(使用include和命名空间namespace):
在这里插入图片描述

页面效果:

在这里插入图片描述

四、路由传参

通过路由路径传参
在这里插入图片描述
我们获取用户列表中的用户id,通过url传参的方式访问用户详情页面。

用户详情的视图函数:

# 用户详情
# 通过id来区分不同用户
def user_detail(request,uid):
    print('uid:',uid)
    user=UserModel.objects.get(pk=uid)   # pk:primary key 主键
    return render(request,'user_detail.html',{'user':user})

用户详情的url(子路由):
通过url路径传参

# 用户详情
# int表示参数的类型为整数
# 通过url传参,url路径中参数的名字需要与视图函数中参数的名字对应
path('userdetail/<int:uid>/',user_detail,name='userdetail'),

用户详情页的html文档(userdetail):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户详情页</title>
</head>
<body>
    <h2>用户详情</h2>
</body>
</html>

通过url来访问用户详情页的页面:
userdetail后的数字表示用户列表中自动生成的id。
在这里插入图片描述

接下来尝试从用户列表页面跳转到用户详情页面:

在用户列表的html文档中使用a标签写上超链接,这里使用带命名空间的反向解析方式进行页面跳转,要通过url传递的参数放在末尾。
在这里插入图片描述
接下来访问用户列表页面:
在这里插入图片描述

通过点击超链接就可以实现页面跳转,点击不同的用户,对应的url的参数不同,因为不同用户的id不同。

点击第一个用户,跳转页面的url是:http://127.0.0.1:8000/App01/userdetail/1/
点击第二个用户,跳转页面的url是:http://127.0.0.1:8000/App01/userdetail/2/
点击第三个用户,跳转页面的url是:http://127.0.0.1:8000/App01/userdetail/3/
……

在用户详情页展示用户的信息,因为通过id可以跳转到不同用户页面,所以要在id对应的用户页面展示该用户的信息。

我们通过视图函数user_detail将用户信息传递给模板user_detail.html,在userdetail页面将用户的姓名和年龄显示出来。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五、路由传递多个参数

  • 视图函数
# 路由传递多个参数
def user_ab_view(request,a,b):
    return HttpResponse(f'a:{a} - b:{b}')
  • 路由
# 路由传递多个参数
    path('userab/<int:a>/<int:b>/',user_ab_view,name='userab'),

注意,在使用的时候,视图函数中的参数名要和路由中的参数名保持一致,名字对应赋值。

访问userab页面,后面必须要跟上两个参数a和b,a和b都是整数。我们通过HttpResponse返回的是a和b的值。
在这里插入图片描述

六、重定向Redirect

需要在视图函数中导入redirect和reverse。
在这里插入图片描述

reverse(name)获取到的是该name对应的路由的路径,如,reverse(‘index’)获取到的是’index/',args表示位置传参,kwargs表示的是关键字传参。

使用redirect进行的是页面跳转,这种跳转在后台是在视图函数之间进行跳转。

在视图函数中进行页面跳转——重定向:
(1) 访问外部页面

  • 视图函数
# 在视图函数中进行页面跳转——重定向
# 在内部进行自动跳转,而不是点击跳转
def my_redirect(request):
    return redirect('https://www.sogou.com')
  • 路由
# 重定向
# 从mydirect页面跳转到别的页面,但是不会从别的页面跳转过来
path('myredirect/',my_redirect),

访问myredirect页面会自动跳转https://www.sogou.com

(2)访问本地路径

def my_redirect(request):
    # return redirect('https://www.sogou.com')
    return redirect('/App01/userlist/')

访问mydirect会自动跳转userlist页面。

(3)使用反向解析(带命名空间)——位置参数传参

注意:使用带命名空间的反向解析时,跟路由中也对应的要使用命名空间。

跟路由:

    # 3.使用子路由(include和命名空间namespace)
    # 使用include和命名空间namespace
    path('App01/',include(('App01.urls','App01'),namespace='App01')),

位置参数传参需要使用reverse中的args参数,以元组的形式传参。

使用带命名空间的反向解析,进行重定向时,reverse中需要写namespace:name,namespace即应用对应的命名空间,name即要跳转的路由的name。

视图函数:

# 在视图函数中进行页面跳转——重定向
# 在内部进行自动跳转,而不是点击跳转
def my_redirect(request):
    # 访问外部页面
    # return redirect('https://www.sogou.com')
    # 访问本地路径
    # return redirect('/App01/userlist/')

    # 反向解析
    # 跟路由中用到了namespace,在重定向中使用反向解析时需要和跟路由中的写法保持一致
    # 如果使用的是带命名空间的反向解析,那么在进行重定向时就要写命名空间
    # 如果使用的是不带命名空间的反向解析,那么在重定向时就不需要带命名空间
    # 如果要跳转的路由中有参数,那么在重定向时需要写上arg参数(元组形式)
    # reverse('App01:userdetail',args=(1,))  ——>  userdetail/1/
    return redirect(reverse('App01:userdetail',args=(1,)))

在反向解析的重定向中,获取到要跳转的路由的name之后,进行路由匹配,找到name对应的path,获取路径为"userdetail/int:uid/",通过args传递的参数同时传递给路由url中的参数。如:reverse(‘App01:userdetail’,args=(1,)) ——> userdetail/1/

路由:

# 用户详情
# int表示参数的类型为整数
# 通过url传参,url路径中参数的名字需要与视图函数中参数的名字对应
path('userdetail/<int:uid>/',user_detail,name='userdetail'),

访问myredirect页面就会自动跳转到对应的用户详情页。
在这里插入图片描述

(4)使用反向解析(带命名空间)——关键字参数传参

关键字参数传参需要使用reverse中的kwargs参数,以字典形式传参。

关键字参数传参的字典中的键对应要跳转的路由中的参数,名字要一致。字典形式也可以给多个参数传参,写成多对键值对形式。


# 在视图函数中进行页面跳转——重定向
# 在内部进行自动跳转,而不是点击跳转
def my_redirect(request):
    # 访问外部页面
    # return redirect('https://www.sogou.com')
    # 访问本地路径
    # return redirect('/App01/userlist/')

    # 反向解析
    # 跟路由中用到了namespace,在重定向中使用反向解析时需要和跟路由中的写法保持一致
    # 如果使用的是带命名空间的反向解析,那么在进行重定向时就要写命名空间
    # 如果使用的是不带命名空间的反向解析,那么在重定向时就不需要带命名空间
    # 如果要跳转的路由中有参数,那么在重定向时需要写上arg参数(元组形式)
    # reverse('App01:userdetail',args=(1,))  ——>  userdetail/1/
    # return redirect(reverse('App01:userdetail',args=(1,)))

    # 关键字参数传参
    # 关键字参数传参需要使用reverse中的kwargs参数,以字典形式传参。
    return redirect(reverse('App01:userdetail',kwargs={'uid':2}))

访问myredirect页面会自动跳转http://127.0.0.1:8000/App01/userdetail/2/ 。

(5)反向解析(不带命名空间)

注意:使用不带命名空间的反向解析时,跟路由中也对应的不可以使用命名空间。

跟路由:

    # 2.使用子路由,使用include
    # 一个应用对应一个子路由
    path('App01/',include('App01.urls')),

视图函数:

# 在视图函数中进行页面跳转——重定向
# 在内部进行自动跳转,而不是点击跳转
def my_redirect(request):
    # 1.访问外部页面
    # return redirect('https://www.sogou.com')
    # 2.访问本地路径
    # return redirect('/App01/userlist/')

    # 3.反向解析(带命名空间)
    # 跟路由中用到了namespace,在重定向中使用反向解析时需要和跟路由中的写法保持一致
    # 如果使用的是带命名空间的反向解析,那么在进行重定向时就要写命名空间
    # 如果使用的是不带命名空间的反向解析,那么在重定向时就不需要带命名空间
    # 如果要跳转的路由中有参数,那么在重定向时需要写上arg参数(元组形式)
    # reverse('App01:userdetail',args=(1,))  ——>  userdetail/1/
    # return redirect(reverse('App01:userdetail',args=(1,)))

    # 关键字参数传参
    # 关键字参数传参需要使用reverse中的kwargs参数,以字典形式传参。
    # return redirect(reverse('App01:userdetail',kwargs={'uid':2}))

    # 4.反向解析(不带命名空间)
    return redirect(reverse('userdetail',args=(1,)))

注意:如果使用了命名空间,那么后面的反向解析(包括视图函数和模板中)都要使用命名空间,否则会报错。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值