前言html
URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码对应执行。python
urls.py: 请求路径与视图函数的映射关系正则表达式
注意url()是1版本的,path()是2版本的django
from django.conf.urls import url urlpatterns = [ url(正则表达式, views视图,参数,别名), url(r'^articles/2003/$', views.special_case_2003), #为何咱们不在函数名后加()呢?由于启动Django的
补充:bash url(r'^$', views.index), # 匹配根路径 url(r'', views.index), # 匹配根路径,这样会形成问题,这个语句放在最上面那么,访问全部网页都将走这个匹配 |
注意:app
补充:ide
# 是否开启URL访问地址后面不为/跳转至带有/的路径的配置项
APPEND_SLASH=True
Django settings.py配置文件中默认没有 APPEND_SLASH 这个参数,但 Django 默认这个参数为 APPEND_SLASH = True。 其做用就是自动在网址结尾加'/'。函数
其效果就是:工具
咱们定义了urls.py:post
from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^blog/$', views.blog), ]
访问 http://www.example.com/blog 时,默认将网址自动转换为 http://www.example/com/blog/ 。
若是在settings.py中设置了 APPEND_SLASH=False,此时咱们再请求 http://www.example.com/blog 时就会提示找不到页面。
经过正则分组获取url中的动态参数
(正则匹配得到的参数是字符串)
1 from django.contrib import admin 2 from django.urls import path,re_path 3 from app01 import views 4 5 6 urlpatterns = [ 7 path('admin/', admin.site.urls), 8 path('timer/', views.timer), 9 path('articles/2003/', views.special_case_2003), #special_case_2003(request) 10 re_path(r'articles/(\d{4})/$', views.year_archive) , #year_archive(request,分组匹配的那个参数) 11 # 匹配正则使用re_path,re_path等同于url,因此默认是没有^或$ 12 re_path(r'articles/(\d{4})/(\d{2})/', views.year_month) 13 ] 14 15 ''' 16 请求的url的路径部分与url方法的正则表达式进行匹配,一旦匹配成功,则执行对应的视图函数 17 http://127.0.0.1:8000/articles/2003/ 18 path="/articles/2003/" 19 20 经过下面的方法循环匹配,匹配成功则执行对应函数: 21 for item in urlpatterns: 22 ret=re.search(item.regex,path) # re.search("^articles/\d{4}/$","articles/2008/") 23 if ret: 24 item.function(request) 25 '''
给分组起一个名字,实现关键字传参
上面的示例使用简单的、没有命名的正则表达式组(经过圆括号)来捕获URL 中的值并以位置 参数传递给视图。在更高级的用法中,可使用命名的正则表达式组来捕获URL 中的值并以关键字 参数传递给视图。
在Python 正则表达式中,命名正则表达式组的语法是(?P<name>pattern)
,其中name
是组的名称,pattern
是要匹配的模式。
重写urls.py
1 from django.contrib import admin 2 from django.urls import path,re_path 3 from app01 import views 4 5 6 urlpatterns = [ 7 path('admin/', admin.site.urls), 8 path('timer/', views.timer), 9 path('articles/2003/', views.special_case_2003), #special_case_2003(request) 10 re_path(r'articles/(\d{4})/$', views.year_archive) , #year_archive(request,分组匹配的那个参数) 11 # 匹配正则使用re_path,re_path第一个参数默认有^尖角号 12 # re_path(r'articles/(\d{4})/(\d{2})/', views.year_month), 13 re_path(r'articles/(?P<year>\d{4})/(?P<month>\d{2})/', views.year_month) #year_month(request,year=,month=)关键字参数。在views视图函数中,对应的函数的参数的形参要和分组名保持一致 14 ]
这个实现与前面的示例彻底相同,只有一个细微的差异:捕获的值做为关键字参数而不是位置参数传递给视图函数
在实际应用中,这意味你的URLconf 会更加明晰且不容易产生参数顺序问题的错误 —— 你能够在你的视图函数定义中从新安排参数的顺序。固然,这些好处是以简洁为代价;
补充:视图函数中指定默认值
1 # urls.py中 2 from django.conf.urls import url 3 4 from . import views 5 6 urlpatterns = [ 7 url(r'^blog/$', views.page), 8 url(r'^blog/page(?P<num>[0-9]+)/$', views.page), 9 ] 10 11 # views.py中,能够为num指定默认值 12 def page(request, num="1"): 13 pass
给每个app本身的url分发各自的路由文件中
项目中咱们把每一个应用中的urls.py文件都单独放在各自的应用文件中,这样就须要总urls.py文件和各个应用中的urls.py文件联系起来,这就是从总文件中分发给各个分文件。在各个应用中须要本身建立urls.py文件
项目的urls.py
1 from django.contrib import admin 2 from django.urls import path,re_path,include 3 from app01 import views 4 5 6 urlpatterns = [ 7 # 先匹配app01/而后去app01.urls文件中匹配其余的 8 path(r'app01/',include('app01.urls')) 9 ] 10 11 #如访问http://127.0.0.1:8001/app01/articles/2009/
不要硬编码url,经过别名解析url
当咱们的根据须要访问的路径须要更更名字时,那么,原来的路径就不能访问了。因此就须要更改项目中的相应有关系的这个名。但这样太过于麻烦,一个项目中,对于这个路径,可能有不少使用这个名字。这样维护成本过高,那么该怎么办呢?咱们的想法是用变量之类的方式,总之写路径时不要写死。下面就用别名的方法,只要写别名就行,那么一个地方更名就好了。
如urls.py文件中,起别名
url(r'^login.html/', views.login,name="XXX")
其余相关的别的文件中填写这个路径的只须要写别名
(1)模板文件中(html文件):
<form action="{% url 'XXX' %}" method="post"> 用户名 <input type="text" name="user"> 密码 <input type="password" name="pwd"> <input type="submit"> </form>
当查询到有到
{% url 'XXX' %}就会去url里面寻找对应别名的真实名字把{% url 'XXX' %}替换成真名
(2)视图函数(py文件)
1 urlpatterns = [ 2 path('index/', views.index,name='in_dex'), 3 ]
1 from django.urls import reverse 2 3 def index(request): 4 # 找别名,获得最新的路径放在别名的位置 5 url=reverse("in_dex") 6 print(url)
如urls.py文件中,起别名,有动态的正则,那么该怎么办呢?
re_path('books/delete/(\d+)', views.delete,name='delete')
在html模板文件中这样引用:
{% url 'delete' book.nid %} 把对应的动态的参数放在别名后面
在py文件中
from django.urls import reverse return redirect(reverse("delete",args=(book.nid))) # redirec重定向一个页面,reverse()是用路由解析时须要加上
在须要URL 的地方,对于不一样层级,Django 提供不一样的工具用于URL 反查:
django.core.urlresolvers.reverse()
函数。urls.py:
from django.conf.urls import url from . import views urlpatterns = [ #... url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'), #... ]
在模板中:
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a> <ul> {% for yearvar in year_list %} <li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li> {% endfor %} </ul>
在python中:
from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect def redirect_to_year(request): # ... year = 2006 # ... return HttpResponseRedirect(reverse('news-year-archive', args=(year,))) # 同redirect("/path/")
当命名你的URL 模式时,请确保使用的名称不会与其它应用中名称冲突。若是你的URL 模式叫作comment
,而另一个应用中也有一个一样的名称,当你在模板中使用这个名称的时候不能保证将插入哪一个URL。在URL 名称中加上一个前缀,好比应用的名称,将减小冲突的可能。咱们建议使用myapp-comment
而不是comment
。
命名空间(英语:Namespace)是表示标识符的可见范围。一个标识符可在多个命名空间中定义,它在不一样命名空间中的含义是互不相干的。这样,在一个新的命名空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,由于已有的定义都处于其它命名空间中。
上面反向解析中,因为name没有做用域,Django在反解URL时,会在项目全局顺序搜索,当查找到第一个name指定URL时,当即返回。咱们在开发项目时,会常用name属性反解出URL,当不当心在不一样的app的urls中定义相同的name时,可能会致使URL反解错误,为了不这种事情发生,引入了命名空间。以下示例:
项目下urls.py文件:
urlpatterns = [
url(r'^admin/', admin.site.urls),
re_path(r'^app01/', include(('app01.urls',"app01"),namespace='app01')),
re_path(r'^app02/', include(('app02.urls',"app02"),namespace='app02')),
]
app01下的urls.py:
urlpatterns = [ url(r'^index/', index, name="index"), ]
app02下的urls.py:
urlpatterns = [ url(r'^index/', index, name="index"), ]
app01下的views.py:
from django.core.urlresolvers import reverse def index(request): return HttpResponse(reverse("app01:index"))
app02下的views.py:
from django.core.urlresolvers import reverse def index(request): return HttpResponse(reverse("app02:index"))
Django1版本 的路由层(URLconf):https://www.cnblogs.com/yuanchenqi/articles/8876685.html
Django2版本 的路由层(URLconf):https://www.cnblogs.com/yuanchenqi/articles/8931472.html