Django之url函数、有名无名分组、反向解析、url转换器
一、
1、django 1.x 版本中使用的是url
url('test', views.test), url函数的第一个参数是支持正则表达式的 如果匹配到一个路由,就不在往下匹配,直接执行路由对应的视图函数
2、http://127.0.0.1:8000/test/
/是django默认设置的,django会先拿着test去匹配,如果匹配不到,它会自动加一个斜杠再次去匹配
APPEND_SLASH = False # 设置默认不斜杠匹配
3、django 2.x 版本中使用的是path
path('test/', admin.site.urls), # path是不支持正则的,它是精准匹配,输入的内容和路由地址必须是完全不配
re_path支持正则
re_path('^test/$', admin.site.urls) # django1中的url是完全一样的
二、无名、有名分组
无名分组和有名分组在Django的URL配置中用于捕获动态部分,并将其传递给视图函数,让你能够轻松处理动态URL的情况,并且提高代码的可读性。
有名分组和无名分组不要一起使用
1、无名分组(django1)
urlpatterns = [ url('^test/(\d+)/(\d+)$', views.test), ]
上述的url中有两个无名的()分组,需要将两个参数写到视图函数中
无名分组就是把路由地址匹配的的数据以位置参数的形式传递给视图函数
def test(request, xx, yy): print(xx, yy) # 123 return HttpResponse("test")
2、有名分组(django1)
urlpatterns = [ url('^testadd/(?P<year>\d+)/(?P<month>\d+)$', views.testadd) ]
有名分组就是把路由地址匹配的的数据以关键字参数的形式传递给视图函数
def testadd(request, year, ,month): print(year, month) return HttpResponse("test")
django2中的用法
re_path('^test/(\d+)/(\d+)/(\d+)/(\d+)/(\d+)/(\d+)/(\d+)$', views.test), re_path('^testadd/(?P<year>\d+)/(?P<month>\d+)/(?P<month>\d+)/(?P<month>\d+)$', views.testadd)
三、反向解析
本质是:给路由起一个名字,然后通过一个方法可以解析出这个名字对应的路由地址
反向解析使你能够以更动态和灵活的方式生成URL,避免硬编码URL,提高代码的可维护性,并为重定向和链接生成提供了便利的方法
1、书写位置:
路由层 urlpatterns的第三个参数
urlpatterns = [ path('articles/<int:article_id>/', views.article_detail, name='article_detail'), ]
补充:
str: 匹配除了路径分隔符('/')之外的任何非空字符串。这是默认的转换器。 path('articles/<str:slug>/', views.article_detail) int: 匹配正整数,包括零。 path('articles/<int:year>/', views.year_archive) slug: 匹配由 ASCII 字母或数字,连字符或下划线组成的字符串。 path('tag/<slug:tag_slug>/', views.tag_detail) uuid: 匹配格式化为 UUID 的字符串。 path('order/<uuid:order_id>/', views.order_detail) path: 匹配任何非空字符串,包括路径分隔符。这允许您匹配完整的 URL 路径。 path('pages/<path:page_path>/', views.page_detail)
在这些转换器中,路径参数(例如 <str:slug>
或 <int:year>
)由两部分组成:转换器类型和参数名。转换器类型告诉 Django 如何匹配和转换 URL 中的部分,参数名则是在视图函数中使用的变量名。例如,对于路径 'articles/<str:slug>/'
,它会匹配类似 'articles/example-slug/'
的 URL,并将 'example-slug'
作为一个名为 slug
的字符串参数传递给视图函数。
2、后端解析
如:访问某一个页面,该视图函数下解析路由层的某一个名字
urls:
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^test/v1/', views.test, name='test'), url(r'^home/', views.home), ]
views:需要导入 reverse方法
from django.shortcuts import render, HttpResponse, redirect, reverse def test(request): print('123') return HttpResponse('test') # home视图函数解析test,解析到test的url的地址 def home(request): print(reverse('test')) return HttpResponse('home')
3、 前端解析
<a href="{% url 'test' %}">点我</a>
4、无名分组反向解析
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^test/(\d+)$/', views.test, name='test'), url(r'^home/', views.home), ]
解决:
views中给test设置一个位置形参
def test(request, xx): print(xx) return HttpResponse('test') def home(request): print(reverse('test', args=(1, ))) # 后端解析 return render(request, 'fx.html') # 前端html页面中解析随便传一个数字 <a href="{% url 'test' 123 %}">点我</a>
无名分组反向解析案例
## urls # 修改用户的路由做一个匹配 urlpatterns = [ url(r'^user_edit/(\d+)$', views.user_edit, name="edit_user"), url(r'^user_del/', views.user_del), ## 修改用户信息 def user_edit(request, id): # print(reverse('edit_user', args=(id,))) # /user_edit/1 ... ###前端主页面的使用前端解析{% url 'edit_user' user.id %} {# GET 传参 #} <a href="{% url 'edit_user' user.id %}" class="btn btn-success">修改</a> <a href="/user_del/?id={{ user.id }}" class="btn btn-danger">删除</a>
5、
#### urlpatterns = [ url(r'^test/(?P<year>\d+)/(?P<month>\d+)>/$', views.test, name='test1'), url(r'^home/', views.home), ] #### views def test(request, year, month): print(year, month) return HttpResponse(f'{year}:{month}') def home(request): print(reverse('test1', kwargs={'year': 2023, 'month': 7})) # 后端解析 return render(request, 'fx.html')
注意有名分组的写法:
(?P<year>\d+)/
前端解析
<a href="{% url 'test1' 2023 12 %}">点我</a>
四、路由分发
目前一个django项目只有一个总路由文件urls.py,但是当我们的路由比较多的时候,这个文件就会产生很多的路由地址,产生的问题就是理由比较臃肿,
不太容易管理,也不太容易排查错误。针对每一个应用也可以有自己的路由文件,每一个应用下的路由我们称之为是子路由。
每一个应用下面没有urls.py这个文件,需要自己手动创建出来一个文件
这个时候总路由的作用就是分发了,总路由就不再执行具体的视图函数,而是交给子路由
主路由文件:
from django.conf.urls import url, include from django.contrib import admin from app01 import views from app01 import urls as app01_urls from app02 import urls as app02_urls urlpatterns = [ url(r'^test/(?P<year>\d+)/(?P<month>\d+)>/$', views.test, name='test1'), url(r'^home/', views.home), # 路由分发 # 第一种方式 # url('^app01/', include(app01_urls)), # url('^app02/', include(app02_urls)), # 第二种方式 url('^app01/', include('app01.urls')), url('^app02/', include('app02.urls')), ] #######django2 中,主urls中写法如下 re_path('^app02/', include('app02.urls')), ## 注意,将路由分发写在前面,容易出问题
注 :
需要导入include 方法且 url()中没有 r
from django.conf.urls import url from app02 import views urlpatterns = [ url(r'^index/', views.index), ] #####views from django.shortcuts import render, HttpResponse # Create your views here. def index(request): return HttpResponse('app02_index')
五、
http://127.0.0.1:8000/app01/index
https://www.cnblogs.com/fanshaoO/p/17592993.html # 其实就是伪静态之后的地址
原本这个地址是动态的,数据是从数据库中查询出来的,而不是在html页面中写死的
作用就是让搜索引擎增大seo的查询力度,言外之意就是让我们的页面能够更加容易的被搜索引擎搜索出来
# 比如你在百度中搜索一个关键词,百度的搜索引擎就会去全网搜索数据 # 其实搜索引擎(百度、谷歌、bing、等)就是一个巨大的爬虫程序 # 因为静态的页面更加容易被搜索引擎抓到,这个称之为是seo # seo就是优化你们的产品能够被更容易的搜多到 SEO---------------------->一般是通过技术手段等实现 SEM---------------------->它是需要收费的,其实就是广告
2、实现
urlpatterns = [ url(r'^index.html/', views.index), ]
访问