Router介绍
在实际开发过程中,一个Django项目会包含很多的app,这时候如果我们只在主路由里进行配置就会显得杂乱无章,所以通常会在每个app里,创建各自的urls.py路由模块,然后从根路由出发,将app所属的url请求,全部转发到相应的us.py模块中。而这个从主路由转发到各个应用路由的过程叫做路由的分发
路由匹配
# 使用ur1给视图函数传参数path('index/',index)path('detail/<int:id>/',detail)
# 给ur1取别名,那么在使用此ur1的地方可以使用别名。比如:path('index/',index,name='index')path('detail/<int:id>/',detail,name='detail')
命名空间
在实际应用中,Django中可能存在多个应用程序,每个应用程序都可能有自己的路由模块。为了防止路由冲突,Django提供了命名空间(namespace)的概念。命名空间是一种将路由命名为层次结构的方式,使得在查询路由时可以限定在该命名空间内。
# 在根路由中可以设置命名空间path('app/',include(('App.urls',"App"),namespace='App'))
反向解析
Django路由反向解析是一个非常重要的功能,它可以让我们在代码中使用路由别名替代URL路径,在修改URL时避免代码中的硬编码依赖,同时也可以提高可读性和可维护性。
为什么叫反向解析呢? 正常的路由匹配,都是通过path路由规则一步一步找到.html文件。而反向解析因为有路由别名的原因,是直接从.html文件找到路由规则的
# 在视图函数中,反向解析ur1:from django.shortcuts import render,redirect,reversedef 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中:{% ur1 'App:index' %}
路由使用
创建名App的应用
App/models.py
from django.db import models# Create your models here.
class UserModels(models.Model):name=models.CharField(max_length=30)age=models.PositiveIntegerField() # 非负数
App/urls.py
from django.urls import path
from App.views import *urlpatterns=[# 首页path('index/',index)
]
urls.py
from django.contrib import admin
from django.urls import path,include
from App.views import *urlpatterns = [# 1、直接使用根路由path('user/',index),# 2、使用子路由,使用includepath('user/',include('App.urls')),# 3、使用子路由,使用include,命名空间namespace# 使用命名空间时注意,include函数有两个参数,默认第二个参数namespace为None# 当传命名空间的时候,第一个参数要是元组类型的,并且要加上App的名字,一般和应用的名字一样path('user/',include(('App.urls','App'),namespace='App')),path('admin/', admin.site.urls),
]
页面跳转
- 当路由规则使用了命名空间,反向解析也只能使用带命名空间的方式
创建userlist.html,使用index.html进行后端跳转
index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>首页</title>
</head>
<body><h2>首页</h2><hr>{# 1、URL路径 #}{# 当访问这个路径/user/userlist 相当于会访问后端的视图函数userlist(),来到urls.py文件对userlist的路由规则 #}<a href="/user/userlist">url路由的方式:进入用户列表页面</a><hr>{# 2、反向解析 #}{# userlist 是path路由的name值 #}<a href="{% url 'userlist' %}">反向解析的方式:进入用户列表页面</a><hr>{# 反向解析:带命名空间 #}<a href="{% url 'App:userlist' %}">反向解析带命名空间的方式:进入用户列表页面</a>
</body>
</html>
views.py添加
# 用户列表
def usr_list(request):users=UserModels.objects.all()return render(request,'user_list.html',{'users':users})
路由传参
单个参数
创建userdetail.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>用户详情</title>
</head>
<body><h2>用户详情</h2><hr>用户姓名:{{ user.name }}<hr>用户年龄:{{ user.age }}
</body>
</html>
修改user_list.html
<a href="{% url 'userdetail' user.id %}">
通过用户id拼接从而,当通过反向解析跳转到path匹配路径时,会将user.id 传入路由
<!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 'userdetail' user.id %}">{{ user.name }}-{{ user.age }}</a></li>{% endfor %}</ul>
</body>
</html>
views.py添加
# 用户详情
def user_detail(request,uid):print('uid:',uid)# 通过主键获取一个对象的值user=UserModels.objects.get(pk=uid) # pk: primary key 主键return render(request,'userdetail.html',{'user':user})
usrls.py
from django.urls import path
from App.views import *urlpatterns=[# 首页path('index/',index),# 用户列表path('userlist/',usr_list,name='userlist'),# 用户详情path('userdetail/<int:uid>/',user_detail,name='userdetail'),
]
多个参数
- 要和路由中的参数名一致,名字对应赋值,理解为关键字传值
views.py添加
# 多个参数
def user_ab_viem(request,a,b):return HttpResponse(f'a:{a}-b:{b}')
# 要和路由中的参数名一致,名字对应赋值
def user_ba_viem(request,b,a):return HttpResponse(f'a:{a}-b:{b}')
urls.py
from django.urls import path
from App.views import *urlpatterns=[# 首页path('index/',index),path('userlist/',usr_list,name='userlist'),path('userdetail/<int:uid>/',user_detail,name='userdetail'),path('userab/<int:a>/<int:b>/',user_ab_viem,name='userab'),path('userba/<int:a>/<int:b>/',user_ab_viem,name='userba'),
]