Django目录:https://www.jianshu.com/p/dc36f62b3dc5
什么是路由层
URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码对应执行。
简单的路由配置
普通配置
from django.contribimport admin
from django.urlsimport path
from app01import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/',views.index),
]
这是普通配置,一个路由代表一个视图,这样适用于首页这些固定的页面。
无名分组
假如我们要一个功能是能够通过页面查看每天的日志,我们总不能每天都加一个页面来放日志,我们需要批量处理路由。既然路由是个字符串,那么正则显然是一个适合的处理方式。
urls.py
from django.contribimport admin
from django.urlsimport path
from app01import views
urlpatterns = [
re_path(r'^Journal/2019/$', views.special_case_2019),
re_path(r'^Journal/([0-9]{4})/$', views.year_archive),
re_path(r'^Journal/([0-9]{4})/([0-9]{2})/$', views.month_archive),
re_path(r'^Journal/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail)
]
viers.py
def special_case_2019(request):
return HttpResponse("Using the special_case_2019 function")
def year_archive(request,year):
return HttpResponse("Using the year_archive function "+str(year))
def month_archive(request,year,month):
return HttpResponse("Using the month_archive function "+str(year)+" "+str(month))
def article_detail(request,year,month,day):
return HttpResponse("Using the article_detail function "+str(year)+" "+str(month)+" "+str(day))
这样我们就可以按照符合我们正则表达式的路由分配相应的视图。
例如我们访问:http://127.0.0.1:8080/Journal/2018/05/12/
因为这个url的格式符合路由表第四条,所以使用视图中的article_detail函数。
同时将捕获到的日期也显示出来。
注意:
若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。
不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^Journal而不是^/Journal。
每个正则表达式前面的'r' 是可选的但是建议加上。它告诉Python 这个字符串是“原始的” —— 字符串中任何字符都不应该转义
有名分组
上面的示例使用简单的、没有命名的正则表达式组(通过圆括号)来捕获URL 中的值并以位置 参数传递给视图。在更高级的用法中,可以使用命名的正则表达式组来捕获URL 中的值并以关键字参数传递给视图。
在Python 正则表达式中,命名正则表达式组的语法是(?P
urls.py
from django.contribimport admin
from django.urlsimport path
from app01import views
urlpatterns = [
re_path(r'^Journal/2019/$', views.special_case_2019),
re_path(r'^Journal/(?P
[0-9]{4})/$', views.year_archive), re_path(r'^Journal/(?P
[0-9]{4})/(?P [0-9]{2})/$', views.month_archive), re_path(r'^Journal/(?P
[0-9]{4})/(?P [0-9]{2})/(?P [0-9]+)/$', views.article_detail) ]
这个实现与前面的示例完全相同,只有一个细微的差别:捕获的值作为关键字参数而不是位置参数传递给视图函数。
例如:
Journal/2018/05/12/ 这样的路由请求
调用 views.month_archive(request, year='2018', month='05',day='12')
而不是 views.month_archive(request, '2018', '05','12')。
在实际应用中,这意味你的URLconf 会更加明晰且不容易产生参数顺序问题的错误
既你可以在你的视图函数定义中重新安排参数的顺序。
当然这是以简洁为代价的。
views.py
def special_case_2019(request):
return HttpResponse("Using the special_case_2019 function")
def year_archive(request,year):
return HttpResponse("Using the year_archive function "+str(year))
def month_archive(request,month,year):
return HttpResponse("Using the month_archive function "+str(year)+" "+str(month))
def article_detail(request,day,year,month):
return HttpResponse("Using the article_detail function "+str(year)+" "+str(month)+" "+str(day))
我们将函数的参数顺序颠倒了,然后我们访问:
http://127.0.0.1:8080/Journal/2018/09/
路由分发
路由分发就是当一个url请求过来之后先到项目主目录下的urls内,再由这个url做处理分发给其他app内的urls。
这就需要在app内自己建立一个urls.py文件,每一个app都有一个自己的路由表。
one_exa.urls.py
from django.urlsimport re_path,include
urlpatterns = [
re_path(r'^Journal/', include("app01.urls")),
re_path(r'^echarts/', include("app02.urls")),
]
one_exa.app01.urls.py
from django.urlsimport re_path
from .import views
urlpatterns = [
re_path(r'^$', views.index),
re_path(r'^2019/$', views.special_case_2019),
re_path(r'^(?P
[0-9]{4})/$', views.year_archive), re_path(r'^(?P
[0-9]{4})/(?P [0-9]{2})/$', views.month_archive), re_path(r'^(?P
[0-9]{4})/(?P [0-9]{2})/(?P [0-9]+)/$', views.article_detail) ]
one_exa.app02.urls.py
from django.urlsimport re_path
from .import views
urlpatterns = [
re_path(r'^tq/$', views.tq),
]
使用include将路由下发到app中的路由表中。
我们尝试访问一下:
反向解析与命名空间
参考:https://blog.csdn.net/u014745194/article/details/74010736
首先明确几个概念:
1.在html页面上的内容特别是向用户展示的url地址,比如常见的超链接,图片链接等,最好能动态生成,而不要固定.
2.一个django项目中一般包含了多个django应用(app).
3.一个视图(view)往往对应多个url地址.
随着功能的增加会出现更多的视图,可能之前配置的正则表达式不够准确,于是就要修改正则表达式,但是正则表达式一旦修改了,之前所有对应的超链接都要修改,真是一件麻烦的事情,而且可能还会漏掉一些超链接忘记修改,有办法让链接根据正则表达式动态生成吗? 就是用反向解析的办法。
而在django中实现反向解析URL必备条件就是 url和view能一对一 的匹配,最简单的方式 就是使用name,可以理解为url起了一个名字。
由于name没有作用域,Django在反解URL时,会在项目全局顺序搜索,当查找到第一个name指定URL时,立即返回
我们在开发项目时,会经常使用name属性反解出URL,当不小心在不同的app的urls中定义相同的name时,可能会导致URL反解错误,为了避免这种事情发生,引入了命名空间。
应用范围:1模板中的超链接;2视图中的重定向
使用方法:
定义url时,需要为include定义namespace属性,为url定义name属性
使用时,在模板中使用url标签,在视图中使用reverse函数,根据正则表达式动态生成地址,减轻后期维护成本。
在模板使用url标签的步骤:
在总路由表:
re_path(r'^fxjx/', include("app03.urls",namespace='booktest')),
在app路由表
app_name ='app03'
urlpatterns = [
re_path(r'^fan2/$', views.fan2,name='fan2'),
]
在模板超链接
在视图使用重定向的步骤:
在总路由表:
re_path(r'^fxjx/', include("app03.urls",namespace='booktest')),
在app路由表
app_name ='app03'
urlpatterns = [
re_path(r'^fan2/$', views.fan2,name='fan2'),
]
在视图重定向
from django.core.urlresolvers import reverse
return redirect(reverse('booktest:fan2'))
做一个实例
我们先做模板中的超链接
修改one_exa.urls.py
from django.urls import re_path,include
urlpatterns = [
re_path(r'^Journal/', include("app01.urls")),
re_path(r'^echarts/', include("app02.urls")),
re_path(r'^fxjx/', include("app03.urls",namespace='booktest')),
]
one_exa.app03.urls.py
from django.urls import re_path
from . import views
app_name ='app03'
urlpatterns = [
re_path(r'^fan2/$', views.fan2,name='fan2'),
]
one_exa.app03.views.py
from django.shortcutsimport render
# Create your views here.
def fan2(request):
return render(request,"fan2.html")
one_exa.templates.fan2.html
Title 普通链接:普通fan2
反向解析:反向解析fan2
之后查看页面:
他们的结果是相同的。
之后我们修改一下路由:
页面也发生了改变。
这样一来通过命名空间,无论在templates文件中有多庞大的url地址映射,只要使用url软编码,在更改路由系统的时候,都能自动生成。而如果使用硬链接硬编码 ,就只能在views.py和静态文件中逐个修改url地址,不仅耗费时间,更容易产生错误。
之后做视图中的重定向
这里简单举一个例子,具体可查看下一章视图层。
修改one_exa.urls.py
from django.urlsimport re_path,include
urlpatterns = [
re_path(r'^Journal/', include("app01.urls")),
re_path(r'^echarts/', include("app02.urls",namespace='visible')),
re_path(r'^fxjx/', include("app03.urls",namespace='booktest'))
]
one_exa.app02.urls.py
from django.urlsimport re_path
from .import views
app_name='app02'
urlpatterns = [
re_path(r'^tq/$', views.tq,name='zx'),
]
one_exa.app03.views.py
from django.shortcuts import redirect,reverse
# Create your views here.
def fan2(requests):
return redirect(reverse('visible:zx'))
之后我们访问http://127.0.0.1:8080/fxjx/fan2/
就会直接跳转到http://127.0.0.1:8080/echarts/tq/
视图中的重定向传参
这样只要访问符合语法的网页,就自动跳转到http://127.0.0.1:8080/fxjx/fan110_26/。