schema://host[:port#]/path/.../?query-stringpython
url(r'^test1/9999/$', views.test1.as_view()), #普通用法 url(r'^test2/([0-9]{4})/$', views.test2.as_view()), # 单个非命名参数 url(r'^test3/([0-9]{4})/([0-9]{2})/$', views.test3.as_view()), url(r'^test4/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.test4.as_view()),
咱们先开始建一个django工程 在这里咱们给给工程命名为lesson1 放在Django_lesson文件夹下
具体建django工程的细节详情见Django-0一、初识Django和搭建Django helloworld正则表达式
而后新建一个app 名为urltestdjango
在lesson1.url.py 中导入viewsegmentfault
from urltest import views
在lesson.urls.py中添加如下路由浏览器
url(r'^admin/', admin.site.urls), url(r'^test1/9999/$', views.Test1.as_view()), url(r'^test2/([0-9]{4})/$', views.Test2.as_view()), url(r'^test3/([0-9]{4})/([0-9]{2})/$', views.Test3.as_view()), views.Test4.as_view()),
在urltest.view.py中添加如下视图类服务器
class Test1(View): def get(self, request): msg = "Test1 sucessful" return HttpResponse(msg) class Test2(View): def get(self, request, year): msg = "Test2 sucessful %s 年" % year return HttpResponse(msg) class Test3(View): def get(self, request, year, month): msg = "Test3 sucessful %s 年 %s 月" % (year, month) return HttpResponse(msg)
注:
若要从URL 中捕获一个值,只须要在它周围放置一对圆括号。
不须要添加一个前导的反斜杠,由于每一个URL 都有。例如,应该是^articles 而不是 ^/articles。
每一个正则表达式前面的'r' 是可选的可是建议加上。它告诉Python 这个字符串是“原始的” —— 字符串中任何字符都不该该转义。参见Dive Into Python 中的解释。app
^表明开始匹配,若是只有^符号,则只须要部分匹配成功便可
$表明结束匹配,添加$符号, 通常就表明完整匹配less
咱们的URL匹配规则必定须要保持惟一函数
上面的示例使用简单的、没有命名的正则表达式组(经过圆括号)来捕获URL 中的值并以位置 参数传递给视图。在更高级的用法中,可使用命名的正则表达式组来捕获URL 中的值并以关键字 参数传递给视图。
在Python 正则表达式中,命名正则表达式组的语法是(?P<name>pattern)
,其中name 是组的名称,pattern 是要匹配的模式。工具
url(r'^test4/(?P<year>[0-9]{4})/$', views.Test4.as_view()), url(r'^test5/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.Test5.as_view()),
在urltest.view.py中添加如下视图类
class Test4(View): def get(self, request, year): msg = "Test3 sucessful %s 年" % year return HttpResponse(msg) class Test5(View): def get(self, request, month, year): # 这里咱们交换了year和month的顺序 msg = "Test3 sucessful %s 年 %s 月" % (year, month) return HttpResponse(msg)
若是有命名参数,则使用这些命名参数,忽略非命名参数。
不然,它将以位置参数传递全部的非命名参数。
请求的URL被看作是一个普通的Python 字符串, URLconf在其上查找并匹配。进行匹配时将不包括GET或POST请求方式的参数以及域名。换句话讲,全部的请求方法 —— 即,对同一个URL的不管是POST请求、GET请求、或HEAD请求方法等等 —— 都将路由到相同的函数。
每一个捕获的参数都做为一个普通的Python 字符串传递给视图,不管正则表达式使用的是什么匹配方式。
在任什么时候候,你的urlpatterns 均可以包含其它URLconf 模块。这实际上将一部分URL 放置于其它URL 下面。
在lesson1.urls.py中加入如下代码
from django.conf.urls import include # 导入 include url(r'^test7/', include('urltest.urls')), # 加入路由
在urltest文件夹下新建urls.py加入如下代码
from django.conf.urls import url from urltest import views urlpatterns = [ url(r'^test7/$', views.Test7.as_view()), ]
在urltest.views.py加入如下视图类
class Test7(View): def get(self, request): # 这里咱们交换了year和month的顺序 msg = "Test7 sucessful" return HttpResponse(msg)
URLconfs 具备一个钩子,让你传递一个Python 字典做为额外的参数传递给视图函数。
django.conf.urls.url() 函数能够接收一个可选的第三个参数,它是一个字典,表示想要传递给视图函数的额外关键字参数。
#lesson1.urls.py中加入这个路由 url(r'^test8/', include('urltest.urls'), {'name': 'lethe', 'date': '2018'}), #urltest.urls.py中加入这个路由 url(r'^test8/$', views.Test8.as_view()), #views.py中加入这个视图类 class Test8(View): def get(self, request, name, date): # 这里咱们交换了year和month的顺序 msg = "Test8 sucessful by %s in %s" % (name, date) return HttpResponse(msg)
当Django 找不到一个匹配请求的URL 的正则表达式时,或者当抛出一个异常时,Django 将调用一个错误处理视图。
Http状态码
每个请求,都会返回一个状态
200 : 请求正常
404:找不到页面
403:是指服务器拒绝
400:request异常
500:服务器异常
在URLconf中指定参数,这些参数分别是
handler404
一个callable或一个字符串,表示若是没有URL模式匹配,应该调用的视图的完整Python导入路径。
默认状况下是'django.views.defaults.page_not_found'。
handler500
一个callable或一个字符串,表示若是没有URL模式匹配,应该调用的视图的完整Python导入路径。
默认状况下,这是'django.views.defaults.page_not_found'。
handler403
一个callable或一个字符串,表示若是用户没有访问资源所需的权限,应调用的视图的完整Python导入路径。
默认状况下,这是'django.views.defaults.permission_denied'。
handler400
若是HTTP客户端已发送致使错误条件的请求和状态代码为400的响应,则应调用的可调用或表示完整的Python视图导入路径的字符串。
默认状况下,这是'django.views.defaults.bad_request'。
在settings.py中将DEBUG值改成True
当找不到页面的时候 页面显示以下图
而后咱们再在settings.py中将DEBUG值改成False (咱们通常在开发的时候设置DEBUG值为True 在产品上线的时候将DEBUG值改成False)
当找不到页面的时候 页面显示以下图
咱们将代码做以下更改
#在views.py中加入如下代码 def Error404(request): return HttpResponse("哎呦 404 尴尬了!") #DEBUG值保持为False #在lesson1.py中加入 handler404 = 'urltest.views.Error404'
在使用Django 项目时,一个常见的需求是得到URL 的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向等)。
人们强烈但愿不要硬编码这些URL(费力、不可扩展且容易产生错误)或者设计一种与URLconf 绝不相关的专门的URL 生成机制,由于这样容易致使必定程度上产生过时的URL。
换句话讲,须要的是一个DRY 机制。除了其它优势,它还容许设计的URL 能够自动更新而不用遍历项目的源代码来搜索并替换过时的URL。
要获取一个URL,最初拥有的信息是负责处理它的视图的标识(例如名字),与查找正确的URL 的其它必要的信息如视图参数的类型(位置参数、关键字参数)和值。
Django 提供了一个解决方案使得URL 映射是URL 设计惟一的储存库。你用你的URLconf填充它,而后能够双向使用它:
根据用户/浏览器发起的URL 请求,它调用正确的Django 视图,并从URL 中提取它的参数须要的值。
根据Django 视图的标识和将要传递给它的参数的值,获取与之关联的URL。
第一种方式是咱们在前面的章节中一直讨论的用法。第二种方式叫作反向解析URL、反向URL匹配、反向URL查询或者简单的URL反查。
在须要URL 的地方,对于不一样层级,Django 提供不一样的工具用于URL 反查:
在模板中:使用url 模板标签。
在Python 代码中:使用django.core.urlresolvers.reverse() 函数。
在更高层的与处理Django 模型实例相关的代码中:使用get_absolute_url() 方法。
#在urls.views.py中加入如下代码 url(r'^articles/$', views.Articles.as_view()), #在views.py中加入如下代码 class Articles(View): def get(self, request): return redirect('/test1/9999/')
URL 命名空间容许你反查到惟一的命名URL 模式,即便不一样的应用使用相同的URL 名称。第三方应用始终使用带命名空间的URL 是一个很好的实践(咱们在教程中也是这么作的)。相似地,它还容许你在一个应用有多个实例部署的状况下反查URL。换句话讲,由于一个应用的多个实例共享相同的命名URL,命名空间提供了一种区分这些命名URL 的方法。
一个URL命名空间有两个部分,它们都是字符串:
应用命名空间
它表示正在部署的应用的名称。一个应用的每一个实例具备相同的应用命名空间。例如,能够预见Django 的管理站点的应用命名空间是'admin'。
实例命名空间
它表示应用的一个特定的实例。实例的命名空间在你的所有项目中应该是惟一的。可是,一个实例的命名空间能够和应用的命名空间相同。它用于表示一个应用的默认实例。
URL 的命名空间使用':' 操做符指定。例如,管理站点应用的主页使用'admin:index'。它表示'admin' 的一个命名空间和'index' 的一个命名URL。
命名空间也能够嵌套。命名URL'sports:polls:index' 将在命名空间'polls'中查找'index',而poll 定义在顶层的命名空间'sports' 中。
#在lesson1.urls.py中加入如下路由 url(r'^url1test/', include('urltest.urls_1', namespace='url1test')), url(r'^url2test/', include('urltest.urls', namespace='url2test')), url(r'^url1_login/$', views.ToUrl1Login.as_view()), url(r'^url2_login/$', views.ToUrl2Login.as_view()), #在urltest文件夹下新建url_1.py并加入如下代码 from django.conf.urls import url from urltest import views urlpatterns = [ url(r'^login/$', views.Url1Login.as_view(), name='login'), ] #在urltest.url.py中加入如下路由 url(r'^login/$', views.Url2Login.as_view(), name='login'), # 在views.py中加入如下视图类 class Url1Login(View): def get(self, request): return HttpResponse("我是url1test.login") class Url2Login(View): def get(self, request): return HttpResponse("我是url2test.login") class ToUrl1Login(View): def get(self, request): return redirect(reverse('url1test:login')) class ToUrl2Login(View): def get(self, request): return redirect(reverse('url2test:login'))
当输入/url1_login/时 跳到ToUrl1Login而后跳到url1test:login(即namespace='url1test',name='login'的路由 即/url1test/login/ 打印我是url1test.login)
# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.shortcuts import render from django.views import View from django.http import HttpResponse from django.shortcuts import reverse, redirect # Create your views here. class Test1(View): def get(self, request): msg = "Test1 sucessful" return HttpResponse(msg) class Test2(View): def get(self, request, year): msg = "Test2 sucessful %s 年" % year return HttpResponse(msg) class Test3(View): def get(self, request, year, month): msg = "Test3 sucessful %s 年 %s 月" % (year, month) return HttpResponse(msg) class Test4(View): def get(self, request, year): msg = "Test4 sucessful %s 年" % year return HttpResponse(msg) class Test5(View): def get(self, request, month, year): # 这里咱们交换了year和month的顺序 msg = "Test5 sucessful %s 年 %s 月" % (year, month) return HttpResponse(msg) class Test6(View): def get(self, request, num='1'): # 这里咱们交换了year和month的顺序 msg = "Test6 sucessful num=%s" % num return HttpResponse(msg) class Test7(View): def get(self, request): # 这里咱们交换了year和month的顺序 msg = "Test7 sucessful" return HttpResponse(msg) class Test8(View): def get(self, request, name, date): # 这里咱们交换了year和month的顺序 msg = "Test8 sucessful by %s in %s" % (name, date) return HttpResponse(msg) class Articles(View): def get(self, request): return redirect('/test1/9999/') class Reverse_test(View): def get(self, request): return redirect(reverse('reverse_test', args=('2021',))) class Url1Login(View): def get(self, request): return HttpResponse("我是url1test.login") class Url2Login(View): def get(self, request): return HttpResponse("我是url2test.login") class ToUrl1Login(View): def get(self, request): return redirect(reverse('url1test:login')) class ToUrl2Login(View): def get(self, request): return redirect(reverse('url2test:login')) def Error404(request): return HttpResponse("哎呦 404 尴尬了!")
from django.conf.urls import url, include from django.contrib import admin from urltest import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^test1/9999/$', views.Test1.as_view()), url(r'^test2/([0-9]{4})/$', views.Test2.as_view(), name='reverse_test'), url(r'^test3/([0-9]{4})/([0-9]{2})/$', views.Test3.as_view()), url(r'^test4/(?P<year>[0-9]{4})/$', views.Test4.as_view()), url(r'^test5/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.Test5.as_view()), url(r'^test6/(?P<num>[0-9]+)/$', views.Test6.as_view()), url(r'^test7/', include('urltest.urls')), url(r'^test8/', include('urltest.urls'), {'name': 'lethe', 'date': '2018'}), url(r'^articles/$', views.Articles.as_view()), url(r'^reverse/$', views.Reverse_test.as_view()), url(r'^url1test/', include('urltest.urls_1', namespace='url1test')), url(r'^url2test/', include('urltest.urls', namespace='url2test')), url(r'^url1_login/$', views.ToUrl1Login.as_view()), url(r'^url2_login/$', views.ToUrl2Login.as_view()), ] handler404 = 'urltest.views.Error404'
from django.conf.urls import url from urltest import views urlpatterns = [ url(r'^test7/$', views.Test7.as_view()), url(r'^test8/$', views.Test8.as_view()), url(r'^login/$', views.Url2Login.as_view(), name='login'), ]
from django.conf.urls import url from urltest import views urlpatterns = [ url(r'^login/$', views.Url1Login.as_view(), name='login'), ]
注: 本文章是本人的CSDN博客中对应的文章转过来的