反向解析 无名分组 有名分组 路由层
无名分组与有名分组:
有名分组和无名分组都是为了获取路径中的参数,并传递给视图函数,区别在于无名分组是以位置参数的形式传递,有名分组是以关键字参数的形式传递。
强调:无名分组和有名分组不要混合使用
无名分组:
分组:就是给某一段正则表达式用小括号扩起来
无名分组就是将括号内正则表达式匹配到的内容当作位置参数传递给后面的视图函数
有什么作用?
可以从url地址中解析出参数,传递给视图函数使用
urls.py:
1 2 3 4 5 6 7 8 9 10 | from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r '^admin/' , admin.site.urls), # 下述正则表达式会匹配url地址的路径部分为:article/数字/,匹配成功的分组部分会以位置参数的形式传给视图函数,有几个分组就传几个位置参数 url(r '^aritcle/(\d+)/$' ,views.article), <br> #url(r'^index/(\d+)/(\d+)/(\d+)/',views.index), ] |
views.py:
1 2 3 4 5 6 | from django.shortcuts import render from django.shortcuts import HttpResponse # 需要额外增加一个形参用于接收传递过来的分组数据 def article(request,article_id): return HttpResponse( 'id为 %s 的文章内容...' % article_id) |
测试:python manage.py runserver 8001 # 在浏览器输入:http://127.0.0.1:8001/article/3/
有名分组:
可以给正则表达式起一个别名,有名分组就是将括号内正则表达式匹配到的内容当作关键字参数传递给后面的视图函数
urls.py
1 2 3 4 5 6 7 8 9 10 | from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r '^admin/' , admin.site.urls), # 该正则会匹配url地址的路径部分为:article/数字/,匹配成功的分组部分会以关键字参数(article_id=匹配成功的数字)的形式<br>传给视图函数,有几个有名分组就会传几个关键字参数 url(r '^aritcle/(?P<article_id>\d+)/$' ,views.article), <br> #url(r'^index/(?P<year>\d+)/(?P<age>\d+)/(?P<month>\d+)/',views.index), ] |
views.py
from django.shortcuts import render from django.shortcuts import HttpResponse # 需要额外增加一个形参,形参名必须为article_id def article(request,article_id): return HttpResponse('id为 %s 的文章内容...' %article_id)
测试:python manage.py runserver 8001 # 在浏览器输入:http://127.0.0.1:8001/article/3/
同一个分组可以使用N多次:
"""
# 单个的分组可以使用多次
url(r'^index/(\d+)/(\d+)/(\d+)/',views.index),
url(r'^index/(?P<year>\d+)/(?P<age>\d+)/(?P<month>\d+)/',views.index),
案例
# 这种地址,把人名和id分出来
# 有名分组
# ilovejaney/p/13748739.html
url(r'^(?P<name>.*?)/p/(?P<id>\d+).html', views.article),
# 无名分组
url(r'^(.*?)/p/(\d+).html', views.article),
# 5 伪静态
-原来是动态页面/login 做成/login.html 伪装成静态页面,便于seo优化
-seo优化:
-https://www.cnblogs.com/liuqingzheng/articles/9509792.html
反向解析:
# 通过一些方法得到一个结果 该结果可以直接访问对应的url触发视图函数
# 先给路由与视图函数起一个别名
案例:登录成功跳转到index.html页面
在urls.py文件中
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/$', views.login,name='login_page'), # 路径login/的别名为login_page url(r'^index/$', views.index,name='index_page'), # 路径index/的别名为index_page
在views.py中
from django.shortcuts import render from django.shortcuts import reverse # 用于反向解析 from django.shortcuts import redirect #用于重定向页面 from django.shortcuts import HttpResponse def login(request): if request.method == 'GET': # 当为get请求时,返回login.html页面,页面中的{% url 'login_page' %}会被反向解析成路径:/login/ return render(request, 'login.html') # 当为post请求时,可以从request.POST中取出请求体的数据 name = request.POST.get('name') pwd = request.POST.get('pwd') if name == 'kevin' and pwd == '123': url = reverse('index_page') # reverse会将别名'index_page'反向解析成路径:/index/ return redirect(url) # 重定向到/index/ else: return HttpResponse('用户名或密码错误') def index(request): return render(request, 'index.html')
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录页面</title> </head> <body> <!--强调:login_page必须加引号--> <form action="{% url 'login_page' %}" method="post"> {% csrf_token %} <!--强调:必须加上这一行,后续我们会详细介绍--> <p>用户名:<input type="text" name="name"></p> <p>密码:<input type="password" name="pwd"></p> <p><input type="submit" value="提交"></p> </form> </body> </html>
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <h3>我是index页面...</h3> </body> </html>
测试
python manage.py runserver 8001 # 在浏览器输入:http://127.0.0.1:8001/login/ 会看到登录页面,输入正确的用户名密码会跳转到index.html # 当我们修改路由表中匹配路径的正则表达式时,程序其余部分均无需修改
总结
在views.py中,反向解析的使用: url = reverse('index_page') 在模版login.html文件中,反向解析的使用 {% url 'login_page' %}
混合使用:
url(r'^edit/(\d+)/',views.edit,name='xxx') def edit(request,edit_id): reverse('xxx',args=(edit_id,)) {%for user_obj in user_queryset%} <a href="{% url 'xxx' user_obj.id %}">编辑</a> {%endfor%} # 有名分组反向解析 url(r'^func/(?P<year>\d+)/',views.func,name='ooo') # 前端 <a href="{% url 'ooo' year=123 %}">111</a> 了解 <a href="{% url 'ooo' 123 %}">222</a> 记忆 # 后端 # 有名分组反向解析 写法1 了解 print(reverse('ooo',kwargs={'year':123})) # 简便的写法 减少你的脑容量消耗 记跟无名一样的操作即可 print(reverse('ooo',args=(111,)))
名称空间:
在views.py中,反向解析的使用: url = reverse('index_page') 在模版login.html文件中,反向解析的使用 {% url 'login_page' %}
解决这个问题的方法之一就是避免使用相同的别名,如果就想使用相同的别名,那就需要用到django中名称空间的概念,将别名放到不同的名称空间中,这样即便是出现重复,彼此也不会冲突,具体做法如下
1、总urls.py在路由分发时,指定名称空间
from django.conf.urls import url, include from django.contrib import admin # 总路由表 urlpatterns = [ url(r'^admin/', admin.site.urls), # 传给include功能一个元组,元组的第一个值是路由分发的地址,第二个值则是我们为名称空间起的名字 url(r'^app01/', include(('app01.urls','app01'))), url(r'^app02/', include(('app02.urls','app02'))), ]
2、修改每个app下的view.py中视图函数,针对不同名称空间中的别名'index_page'做反向解析
app01下的views.py
from django.shortcuts import render from django.shortcuts import HttpResponse from django.shortcuts import reverse def index(request): url=reverse('app01:index_page') # 解析的是名称空间app01下的别名'index_page' return HttpResponse('app01的index页面,反向解析结果为%s' %url)
app02下的views.py
from django.shortcuts import render from django.shortcuts import HttpResponse from django.shortcuts import reverse def index(request): url=reverse('app02:index_page') # 解析的是名称空间app02下的别名'index_page' return HttpResponse('app02的index页面,反向解析结果为%s' %url)
在每个app下手动创建urls.py来存放自己的路由,并且为匹配的路径起别名 app01下的urls.py文件 from django.conf.urls import url from app01 import views urlpatterns = [ # 为匹配的路径app01/index/起别名'index_page' url(r'^index/$',views.index,name='index_page'), ] app02下的urls.py文件 from django.conf.urls import url from app02 import views urlpatterns = [ # 为匹配的路径app02/index/起别名'index_page',与app01中的别名相同 url(r'^index/$',views.index,name='index_page'), ]
4 有什么作用
-动态根据路由别名获得路径,一旦路径改变,不需要改其他代码
1、在视图函数中基于名称空间的反向解析,用法如下
url=reverse('名称空间的名字:待解析的别名')
2、在模版里基于名称空间的反向解析,用法如下
<a href="{% url '名称空间的名字:待解析的别名'%}">哈哈</a>
路由匹配
# 路由匹配 url(r'test',views.test), url(r'testadd',views.testadd) """ url方法第一个参数是正则表达式 只要第一个参数正则表达式能够匹配到内容 那么就会立刻停止往下匹配 直接执行对应的视图函数 你在输入url的时候会默认加斜杠 django内部帮你做到重定向 一次匹配不行 url后面加斜杠再来一次 """ # 取消自动加斜杠 APPEND_SLASH = False/True # 默认是自动加斜杠的 urlpatterns = [ url(r'^admin/', admin.site.urls), # 首页 url(r'^$',views.home), # 路由匹配 url(r'^test/$',views.test), url(r'^testadd/$',views.testadd), # 尾页(了解) url(r'',views.error), ]
路由分发
""" django的每一个应用都可以有自己的templates文件夹 urls.py static文件夹 正是基于上述的特点 django能够非常好的做到分组开发(每个人只写自己的app) 作为组长 只需要将手下书写的app全部拷贝到一个新的django项目中 然后在配置文件里面注册所有的app再利用路由分发的特点将所有的app整合起来 当一个django项目中的url特别多的时候 总路由urls.py代码非常冗余不好维护 这个时候也可以利用路由分发来减轻总路由的压力 利用路由分发之后 总路由不再干路由与视图函数的直接对应关系 而是做一个分发处理 识别当前url是属于哪个应用下的 直接分发给对应的应用去处理 """ # 总路由 from app01 import urls as app01_urls from app02 import urls as app02_urls urlpatterns = [ url(r'^admin/', admin.site.urls), # 1.路由分发 url(r'^app01/',include(app01_urls)), # 只要url前缀是app01开头 全部交给app01处理 url(r'^app02/',include(app02_urls)) # 只要url前缀是app02开头 全部交给app02处理 # 2.终极写法 推荐使用 url(r'^app01/',include('app01.urls')), url(r'^app02/',include('app02.urls')) # 注意事项:总路由里面的url千万不能加$结尾 ] # 子路由 # app01 urls.py from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^reg/',views.reg) ] # app02 urls.py from django.conf.urls import url from app02 import views urlpatterns = [ url(r'^reg/',views.reg) ]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南