路由管理:
在实际开发过程中,⼀个Django 项⽬会包含很多的 app ,这时候如果我们只在主路由⾥进⾏配置就会显得杂乱⽆章,所以通常会在每个 app ⾥,创建各⾃的 urls.py 路由模块,然后从根路由出发,将 app 所属的 url 请求,全部转发到相应的 urls.py 模块中。⽽这个从主路由转发到各个应⽤路由的过程叫做路由的分发。
注册app:
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / 'templates',] # 可以多个
,
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
路由匹配:
# 使⽤url给视图函数传参数
path('index/', index)
path('detail/<int:id>/', detail)
# 给url取别名,那么在使⽤此url的地⽅可以使⽤别名。⽐如:
path('index/', index, name='index')
path('detail/<int:id>/', detail, name='detail')
命名空间:
在实际应⽤中,Django中可能存在多个应⽤程序,每个应⽤程序都可能有⾃⼰的路由模块。为了防⽌路由冲突, Django提供了命名空间(namespace)的概念。命名空间是⼀种将路由命名为层次结构的⽅式,使得在查询路由时可 以限定在该命名空间内。
html跳转:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h2>首页</h2>
<hr>
{# url路由 #}
{# 路径是相对于 http://127.0.0.1:8000 注意跳转的/必须要加 的#}
<a href="/user/userlist/">url路由的方式:进入用户列表页面</a>
<hr>
{# 反向解析#}
{# userlist 是path路由的name值#}
{# <a href="{% url 'userlist' %}">反向解析的方式:进入用户列表页面</a>#}
{# <hr>#}
{# 反向解析:带命名空间#}
{# 一个子路由有一个命名空间,然后去子路由去找名称为userlist的映射#}
<a href="{% url 'App:userlist' %}">反向解析带命名空间的方式:进入用户列表页面</a>
</body>
</html>
正向解析: 先有访问url地址,后进行路由映射,然后到html
反向解析:先匹配路由名称,然后定位路由路径,进行路由函数映射
注意:反向解析和命名空间的写法只能保留一种。
{% url 'detail' stu.id %}
{% url 'App:index' %}
<a href="{% url 'App:userdetail' user.id %}">
路由传参:
from django.urls import path, re_path
from App.views import *
urlpatterns = [
# 首页
path('index/', index),
# 用户列表
path('userlist/', user_list, name='userlist'),
# 用户详情
path('userdetail/<int:uid>/', user_detail, name='userdetail'),
# 多个参数
path('userab/<int:a>/<int:b>/', user_ab_view, name='userab'),
# <int:a> 整数
# <str:a> 字符串
path('userba/<int:a>/<int:b>/', user_ba_view, name='userba'),
# 正则的写法: 以前的写法
# re_path(r'userba/(?P<a>\d+)/(?P<b>\d+)/', user_ba_view, name='userba'),
]
from django.http import HttpResponse
from django.shortcuts import render, redirect, reverse
from App.models import *
# 首页
def index(request):
return render(request, 'index.html')
# 用户列表
def user_list(request):
# 获取所有用户数据
users = UserModel.objects.all()
return render(request, 'user_list.html', {'users': users})
# 用户详情
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})
# 多个参数
def user_ab_view(request, a, b):
return HttpResponse(f'a:{a} - b:{b}')
# 要和路由中的参数名一致,名字对应赋值
def user_ba_view(request, b, a):
return HttpResponse(f'a:{a} - b:{b}')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
</head>
<body>
<h2>用户列表</h2>
<hr>
<ul>
{% for user in users %}
<li>
反向解析:路由传参
<a href="{% url 'App:userdetail' user.id %}">
{{ user.name }} - {{ user.age }}
</a>
</li>
{% endfor %}
</ul>
</body>
</html>
App
为命名空间的名字,userdetail
是自己设置的路由名称,{% url 'App:userdetail' user.id %}
,user.id
会作为参数传递个userdetail
这个路由名称所对应的路由。
views.py
# 多个参数
def user_ab_view(request, a, b):
return HttpResponse(f'a:{a} - b:{b}')
# 要和路由中的参数名一致,名字对应赋值
def user_ba_view(request, b, a):
return HttpResponse(f'a:{a} - b:{b}')
urls.py
# 多个参数 相当于关键字参数
path('userab/<int:a>/<int:b>/', user_ab_view, name='userab'),
# <int:a> 整数
# <str:a> 字符串
path('userba/<int:a>/<int:b>/', user_ba_view, name='userba'),
我们看看多个参数怎么传递呢?
但是这种路由的写法是django比较新的写法,下面是比较老的写法,使用正则表达式来进行约束。
# 正则的写法: 以前的写法
re_path(r'userba/(?P<a>\d+)/(?P<b>\d+)/', user_ba_view, name='userba'),
后端重定向:
Django路由反向解析是⼀个⾮常重要的功能,它可以让我们在代码中使⽤路由别名替代URL路径,在修改URL时避 免代码中的硬编码依赖,同时也可以提⾼可读性和可维护性。
views.py
from django.http import HttpResponse
from django.shortcuts import render, redirect, reverse
from App.models import *
# 重定向
def my_redirect(request):
# 反向解析url :会先去找reverse('xx')中的名字,就是路由函数
# return redirect(reverse('index'))
# return redirect(reverse('detail', args=[2]))
# return redirect(reverse('detail', kwargs={"id": 2})
# /a/b 是绝对路径,相当于在端口下拼接
# return redirect('https://www.ifeng.com')
# return redirect('/user/userlist/')
# return redirect('/user/userdetail/2/')
# 反向解析 对应命名空间下的路由名
# reverse('App:userdetail', args=(1,)) => 'userdetail/1/'
# 带命名空间的写法
# return redirect(reverse('App:userdetail', args=(1,))) # 位置参数传参
return redirect(reverse('App:userdetail', kwargs={'uid': 2})) # 关键字传参
# 不带命名空间
# return redirect(reverse('userdetail', args=(1,))) # 位置参数传参
urls.py
# 重定向
path('myredirect/', my_redirect),
注意:有namespace则在后面的html或者重定向或者反向解析都要使用命名空间来写,不然找不到。如果用了命名空间,后面的反向解析(包括视图函数和模板中)都要使用命名空间。
技巧:
在flask或者django中,都是使用模板语言,可以巧用tab提高编程速度。
如果没有提示需要修改配置文件:
总结:
本文深入剖析了Django框架中与路由相关的知识点,包括路由匹配、路由命名空间、HTML中的跳转与Django集成、路由传参以及后端重定向。这些概念和技巧是构建出高效、可扩展Web应用程序的关键要素。
通过全面理解路由匹配机制,我们能够根据URL模式将请求准确地分发到对应的视图函数,实现灵活的路由控制。同时,通过合理使用路由命名空间,我们能够更好地组织和管理路由,提高项目的可维护性和可扩展性。
在前端方面,我们介绍了如何将HTML中的跳转与Django集成,利用模板语言和URL反解析功能,轻松实现页面间的无缝跳转。而通过路由传参,我们可以在URL中传递参数,为视图函数提供所需的数据,实现个性化的页面渲染和处理。
另外,后端重定向是处理用户请求的常见技术之一。通过后端重定向,我们可以根据特定条件将用户重定向到其他URL,实现页面跳转和流程控制,从而提升用户体验和应用程序的功能性。
通过掌握Django路由解析与跳转的全面知识,我们能够构建出强大而稳健的Web应用程序。希望本文能够为你提供深入学习和实践的指导,助你在Django开发中更加熟练和自信。继续探索和应用这些技术,相信你将在Web开发的道路上取得更大的成就。