Python Web开发之Django URL路由--详细总结

     阅读:21

目录

Django路由概念

了解URL

Django路由

URL语法格式详解

url配置

配置流程

 urlpatterns

路由分发

正则匹配

path()与re_path()

 获取url路径的参数

url传递一个参数

 url传递多个参数

反向解析

在模板中进行反解析

在views中使用反向解析

视图

错误视图

自定义错误视图

请求与响应

 HttpRequest定义

响应QueryDict类型

 响应


Django路由概念

了解URL

URL 即统一资源定位符,它是用来表示互联网上的某个资源地址,互联网上的每个文件都有一个唯一的 URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。

Django路由

一个用户向 Web 站点发送请求,是通过 URL 实现的,当 Web 服务器端接收到用户请求后,通过 MTV 的设计模式,我们可以得知,首先用户请求会到达相应的视图函数,那么视图函数是通过路由系统找到到相应的访问资源。

URL语法格式详解

URL 的语法格式为:

protocol://hostname[:port]/path[?query][#fragment]

请看下面的例子:

https://www.baidu.com/movie/movieshow?id=234&number=1314#name

对上述语法格式做简单说明:

1) protocol(协议)

protocol 是指网络传输协议,以下是经常用到的几个协议:

  • http,通过 HTTP 协议访问该资源,格式 http://;
  • https,通过安全的 HTTPS 协议访问该资源, 格式 https://;
  • file,资源是本地计算机上的文件,格式 file:///;
  • ftp,通过 FTP访问资源,格式 FTP://。

2) hostname(主机名)

是指存放资源的服务器的域名、主机名或 IP 地址。有时,在主机名前也可以包含连接到服务器所需的用户名和密码(格式:username:password@hostname)。

3) port(端口号)

port 是一个可选的整数,它的取值范围 是 0-65535。如果 port 被省略时就使用默认端口,各种传输协议都有默认的端口号,如 http 的默认端口为 80,https 的端口是 443。

4) path(路由地址)

由零个或多个/符号隔开的字符串,一般用来表示主机上的一个目录或文件地址。路由地址决定了服务端如何处理这个请求。

5) query (查询)

?开始到#为止,它们之间的部分就是参数,又称搜索部分或者查询字符串。这个部分允许有多个参数,参数与参数之间用&作为分隔符。本例的参数部分为id=234&number=1314

6) fragment(信息片断)

它用于指定网络资源中的片断,例如一个网页中有多个名词解释,那么可使用 fragment 直接对它们定位。例子中的信息片段是#后的 name。#代表网页中的一个位置而 name 就是这个位置的标志符号,当浏览器读取到上述 URL 后,浏览器将直接展示该位置。

视图的响应分为两大类:

1. 以json数据形式返回
2. 以网页的形式返回
           重定向到另一个网页
       错误视图页面(404,500等)
  视图响应的过程:浏览器中发送请求 → urls路由匹配 → 视图响应 → 回馈到浏览器

url配置

配置流程

settings中制定根级url配置文件的路径,根路径配置变了为ROOT_URLCONF,默认为工程目录下的urls.py文件

 urlpatterns

一个url实例的对象,全在根配置搞定,内部由url组成
在django2.0以下的版本中定义url组成:
    url(r‘^learn/’, views.learn)
在django2.0以上版本中定义path和re_path:
    from django.urls import path, re_path
    path(‘learn/’, views.learn)
    或
    re_path(‘learn/’, views.learn)  # re_path中定义的路由地址可以写正则表达式

路由分发

在工程目录的urls.py中编写配置规则,分别引入各各应用中创建的urls.py 文件
在django2.0以下版本中定义路由分发:
    from django.conf.urls import include
    urlpatterns = [
        url(r’^xxx/’, include(‘app.urls’))
    ]
在django2.0以上版本中定义路由分发:
    from django.urls import path, include
    urlpatterns = [
        path('xxx/', include('app.urls'))
        或
        path('xxx/', include(('应用名.urls', '应用名')))
    ]
    
注意:
    路由配置规则注意事项:
        路由匹配时从上到下进行遍历,匹配到就不会继续向后查找了
        匹配的路由前方不需要加反斜杠

路由的语法格进行简单说明:

url(regex,view,name=None)

上述 url 的参数解析如下:

  • regex,匹配请求路径,用正则表达式表示;
  • view,指定 regex 匹配路径所对应的视图函数的名称;
  • name,是给 url 地址起个别名,在模板反向解析的时候使用;

正则匹配

1)正则与正则分组使用

在 Django 的路由系统中,正则匹配得到了充分的使用,比如要匹配任意 1000个页面,那么正则匹配路由地址可以写为:

url(r'^page(\d+)',views.page_view)

同时也可以使用正则分组的方式匹配地址:

r'^(\d+)/(\w{3})/(\d+)' 匹配类似于 http://127.0.0.1:8000/521/Django/1314的地址

2)正则捕获组使用

捕获组:

url(r'^person/(?P<name>\w+)/(?P<age>\d{1,2})',views.person_view)

在视图函数层,用函数关键字传参的方法,将 name 与 age 传递给视图函数。

def person_view(request,name,age):
    s = '姓名: ' + name
    s += ' 年龄: ' + age
    return HttpResponse(s)

一个分组表示一个参数,多个参数需要使用多个分组,并且使用 / 隔开。

path()与re_path()

在 Django 2.0 版本中推出了新的用法 path() 和 re_path(),进一步提升了 Django 的效率与使用的简洁性。2.0 版本以后虽然推出了新的方法,但是 1.0 版本的 URL 用法仍然可以在 2.0 版本中使用,向前做了兼容。

 获取url路径的参数

url传递一个参数

 Django2.0以下版本路由匹配一个参数的规则

如果需要从url中获取一个值,需要对正则加小括号
url(r‘^grade/(\d+)$’, views.getStudent)
注意,url匹配中添加了()取参,在请求调用的函数中必须接收 def getStudent(request, classid)

django2.0以上版本路由匹配一个参数的规则

django2.0以上版本中定义路由时,可以使用path方式和re_path两种方式,如下定义以path形式定义路由。path方式中定义接收参数时,可以指定接受参数的类型:

定义接收参数的语法为: <转换器: 参数名>

定义接受参数的常用转换器为: int,str,uuid,path

例子如下:

定义接受整形的参数:path('params/<int: id>/', views.params)

定义接受字符串的参数:path('params/<str: name/', views.params)

定义接受uuid类型的参数:path('params/<uuid: uid>/', views.params)

定义接受路径path的参数:path('params/<path: path>/', views.params)

注意:使用<转换器:参数名>的形式进行定义接受参数时,接受的类型由转换器指定,参数的值由指定参数名接受。

 url传递多个参数

Django2.0以下版本路由匹配多个参数规则

  1. 使用正在匹配路由中的参数

如果需要获取url路径中的多个参数,那就添加多个括号,默认按照顺序匹配路径名字,参数顺序必须固定
定义url中传递三个参数的地址:
    url(r‘^news/(\d{4})/(\d)+/(\d+)$’, views.getNews)
    实现方法:匹配年月日 def getNews(requests, year, month, day)

      2. 使用关键词获取参数

参数也可以使用关键字参数形式,参数顺序可以任意 url(r’news/(?P\d{4})/(?P\d)+/(?P\d+)$’, views.getNews)

注意:定义路由时定义接受第一个参数的变量为year,接受第二个参数的变量为month,接受第三个参数的变量为day,因此在视图函数中定义接收参数的变量的顺序可以随意的定义。

Django2.0以上版本路由匹配多个参数的规则

定义url中传递三个参数的地址:

path(‘params/<int: year>/<int: month>/<int: day>/’, views.params)
或者
re_path(’params/(?P<year>\d{4})/(?P<month>\d)+/(?P<day>\d+)$’, views.getNews)
或者
re_path(‘params/(\d{4})/(\d+)/(\d+)$’, views.params)
实现方法:匹配年月日 def params(requests, year, month, day)

注意:定义路由时定义接受第一个参数的变量为year,接受第二个参数的变量为month,接受第三个参数的变量为day,因此在视图函数中定义接收参数的变量的顺序可以随意的定义。

反向解析

随着功能的增加,路由层的 url 发生变化,就需要去更改对应的视图层和模板层的 url,非常麻烦,不便维护。

这时我们可以利用反向解析,当路由层 url 发生改变,在视图层和模板层动态反向解析出更改后的 url,免去修改的操作。

反向解析一般用在模板中的超链接及视图中的重定向。

在模板中进行反解析

关键字参数{% url namespace:name key=value key1=value1 %}

在Django2.0以下版本中定义包含url的include语法:

在根urls中定义:
    url(r’^apps/’, include(‘App.urls’, namespace=’app’))
在子urls中定义:
    url(r’^hello/(\d+)’, views.hello, name=’sayhello’)

在Django2.0以上版本中定义包含url的include语法:

在根urls中定义:
path(’apps/’, include((‘app.urls’, 'app'), namespace=’app’))
在应用app的子urls中定义:
path(’hello/<int:id>/’, views.hello, name=’sayhello’)

在模板中使用:​ <a href=’{% url ‘app:sayhello’ grade_id%}’>​ 其中grade_id是参数,其中参数可以使用位置参数,也可以使用关键词参数,和配置urls一样

在views中使用反向解析

使用反向解析优点 如果在视图中,模板中使用硬编码连接,在url配置发生改变时,需要变更的代码会非常多,这样导致我们的代码结构不是很容易维护,使用反向解析可以提高我们代码的扩展性和可维护性

    HttpResponseRedirect(reverse(namespace:name, kwargs = {key1 : value1, key2 : value2}))
    kwargs 是字典

视图

错误视图

位置:通常在应用下的views.py中定义 错误视图:​ 404视图(页面没有被找到 page not found)​ 400视图(客户端操作错误 bad request)​ 403视图(权限错误 403 forbidden )​ 500视图(服务器内部错误 server error)

自定义错误视图

修改debug模式

在工程的settings中修改debug模式: 注意:​ 需要在debug=False的情况下才可以​ 没有关闭debug的情况下会在界面中直接显示错误的信息

在templates文件中定义自己的错误样式

请求与响应

 HttpRequest定义

 服务器在接收到http请求后,会根据报文创建HttpRequest对象
视图中第一个参数就是HttpRequest对象
Django框架会进行自己的包装,之后传递给视图
属性:
    path        请求的完整路径
    method   请求的方法,通常get,post
    Encoding 编码方式,常用utf-8
    Get          类似字典的参数,包含了get的所有参数
    post           类似字典的参数,包含了post的所有参数
    Files         类似字典的参数,包含了上传的文件
    Cookies    字典,包含了所有的COOKIES
    Session    类似字典,表示会话
    方法: is_ajax()   判断是否是ajax(),通常在移动端和js中

响应QueryDict类型

    1)类似字典的结构数据,与字典的区别,可以存在相同的键
    2)GET和POST都是QueryDict对象
    3)QueryDict中数据获取方式
        dict[‘name’] 或者dict.get(‘name’)
        获取指定key对应的所有值
        dict.getlist(‘name’)

 

如下,获取重复提交数据的方法:

 响应

1)可以直接返回一个HttpResponse对象:
    服务器返回给客户端的数据,HttpResponse由程序员自己创建
    不使用模板,直接HttpResponse()
2)可以返回模板
调用模板,进行渲染,直接使用render一步到位
返回表达式:
    render(request, template_name, context)
        request  请求体对象
        template_name  模板路径
        context  字典参数,用来填坑

3)属性
    Content   返回的内容
    Charset   编码格式
    status_code  响应状态码(200,4xx,5xx)
        4xx 客户端的错误
        5xx 服务端的错误
    content_type   MIME类型,定义传输类型的,比如有xml,html,png等等,比如content_type=’image/jpg’
4)方法
    init    初始化内容
    write(xxx) 直接写到文本
    flush 冲刷缓冲区
    set_cookie(key, value=’’, max_age=None, exprise=None)
    delete_cookie(key)   删除cookie,上面是设置
4)重定向
    HttpResponseRedirect响应重定向:可以实现服务器内部的跳转
    Return HttpResponseRedirect(‘/xxx/xxx’)
    使用的时候推荐使用反向解析
    JsonResponse
    使用json数据的请求,通常用在异步请求上jsonResponse(dict)
    content_type是application/json