当你考虑开发现代化、高效且可扩展的网站和Web应用时,Django是一个强大的选择。Django是一个流行的开源Python Web框架,它提供了一个坚实的基础,帮助开发者快速构建功能丰富且高度定制的Web应用

全套Django笔记直接地址: 请移步这里


共 10 章,31 子模块,总计 2w余字


路由配置

学习目标

  • 掌握Django中URL配置
  • 掌握Django URL的匹配流程
  • 掌握URL路径中请求参数的

URL配置

1. URL配置

一、需求

1. 需求: 在浏览器访问URL地址 `ht://127.0.0.1:8000/users/index` 时,显示 `hello django` 信息
2. 实现
   1. 需要编写一个视图函数
      2. 针对该视图函数配置访问路由

二、URL配置实现

1. 对于url访问地址 `ht://127.0.0.1:8000/users/index?a=1`,只需要根据 `users/index` 进行url配置。

**注 意:**前面为了简单,直接在项目下的 urls.py 文件中进行配置,如下

     urlpatterns = [
     ...
     url(r'^users/index$', views.index),
 ]


2. **但 为了减轻项目下的 `urls.py` 文件的配置量,方便url的管理**,会分别在两个`urls.py`文件中进行配置:

* 项目下的 `urls.py` 文件
    
              urlpatterns = [







          # 包含users模块下的urls.py








          # 参数1: 匹配url的正则表达式








          # 参数2: 调用 inclucde 函数,包含users模块下的urls.py






          url(r'^users/', include('users.urls')),
      ]


* `users`应用下的 `urls.py` 文件 (此文件默认不存在,需要自己创建)
    
              urlpatterns = [







          # 配置url和视图函数,需要调用url函数,并传入参数








          # 参数1: 匹配url的正则表达式(需要用 ^ 和 $ 匹配开头和结尾)








          # 参数2: url匹配成功执行的视图函数






          url(r'^index$', views.index), 
      ]

URL配置示例参考:

2. URL匹配流程

URL匹配流程(路由解析顺序):

URL 匹配流程说明

1. 域名、端口、端口后的 `/`,以及查询字符串(问号后面的键值参数)不参与匹配
2. 先到项目下的 `urls.py` 进行匹配,再到应用的 `urls.py` 匹配
3. 根据url配置的先后顺序, **从 上到下**进行URL匹配
4. **在 项目下匹配成功的URL部分会去掉**,剩下的部分继续到应用下作匹配
5. 如果匹配成功,Django会调用对应的视图函数,返回响应内容给浏览器显示
6. 如果最终匹配不成功, `Django` 会给浏览器返回404错误

3. 关于 /index 的两种配置方式

需求: 在浏览器访问URL地址 ht://127.0.0.1:8000/index 时,显示 hello django 信息

配 置方式一: 只在项目的urls.py中配置,应用下不需要作配置

# 项目的urls.py






urlpatterns = [
    url(r'^index$', views.index), 
]

配 置方式二: 在项目和应用的urls.py中都进行配置

# 项目的urls.py






urlpatterns = [






    # 此处正则配置^, 表示任务的字符串都可以匹配成功






    url(r'^', include('users.urls')),
]







# 应用的urls.py






urlpatterns = [
    url(r'^index$', views.index), 
]

捕获URL路径中的参数

一、需求

1. 在服务器端视图中,通过URL路径传递过来的参数
2. 例如: 对于请求URL `ht://127.0.0.1:8000/news/1/2`,需要URL路径中的数值 `1(类别id)` 和 `2(页码)`

二、解决

1. 在配置URL时,可以使用正则表达式匹配 URL 中的参数
2. 需要使用 `小括号` 把要匹配的值 变为正则的一个组, **可 以对组命名,也可以不命名**
3. 【理解】当匹配成功后,Django会自动将匹配成功的值,作为一个方法参数传递到视图函数中

三、代码参考

1. 未命名参数(位置参数): 按定义的顺序传递



     # 在项目下的 urls.py 文件中配置






 url(r'^news/(\d+)/(\d+)$', users.views.news),







 # 在 users/views.py 中定义






 def news(request, a, b):
     return HttpResponse("显示新闻:%s %s" % (a, b))


2. 命名参数(关键字参数): 按定义的组名传递



     # 在项目下的 urls.py 文件中配置






 url(r'^news/(?P<category>\d+)/(?P<page>\d+)$', users.views.news),







 # 在 users/views.py 中定义






 def news(request, category, page):
     return HttpResponse("显示新闻:%s %s" % (category, page))

请求与响应

学习目标

  • 掌握request对象使用
  • 掌握response对象使用
  • 掌握Django中cookie的使用
  • 掌握Django中session的使用

请求对象

一、客户端传参的几种方式

  1. 通过 URL 路径path)传递,例如:127.0.0.1:8000/news/1/2,两个参数:新闻类别id页码

  2. 通过 query string 查询字符串传递

    1. 例如:`127.0.0.1:8000/news?category=1&page=2`
           2. 关于URL格式: `schema://host[:port][path][?query-string][#anchor]`
    
  3. 通过 body 请求体传递,又可根据传递的数据格式,分为:

    1. 键值对:category=1&page=2

      2. 表单数据: 
             3. 非表单数据(json, xml)
      

      {"category": 1, "page": 2}

    <news> <category>1</category> <page>2</page> </news>

  4. 通过 http 协议请求头header)传递

二、HttpRequest对象

一、Django请求和响应过程:

image

二、request对象常用属性:

Attribute Description
path 请求页面的全路径,不包括域名端口参数。例如: /users/index
method 一个全大写的字符串,表示请求中使用的HTTP方法,常用值:GETPOSTDELETEPUT等。以下三种为
GET 请求:
  • form 表单默认提交(或者method指定为get)

  • 在浏览器中输入地址直接请求

  • 网页中的超链接(a标签)
    user |

  • 已登录:AbstractUser对象;

  • 未登录:AnonymousUser对象;
    判断是否已经登录: request.user.is_authenticated(),返回true表示已经登录
    GET | 类似字典的 QueryDict 对象,包含 GET 请求的所有参数
    POST | 类似字典的 QueryDict 对象,包含 POST 请求的所有键值对参数(表单post提交的参数)
    body | 原始的请求体数据,到的数据为 bytes 类型
    META | python 字典类型,封装了请求头headers中的数据
    - REMOTE_ADDR - 客户端的IP地址
    - REQUEST_METHOD -- 一个字符串,例如"GET" 或"POST
    - CONTENT_TYPE - 请求的正文的MIME 类型

**注 意:**对于用户添加到请求头中的键值,Django会给键加上前缀 HTTP_再转换成大写,再把键值保存到request.META中
COOKIES | 一个标准的 python 字典,包含所有的 cookies, 键和值都是字符串
session | 可读可写的类似字典的对象: django.contrib.sessions.backends.db.SessionStoreDjango 提供了 session 模块,默认就会开启用来保存 session 数据

三、QueryDict对象

  • 所在的包: django.http.QueryDict

  • HttpRequest 对象中的 GETPOST 属性 都是 QueryDict类型

  • 与python字典不同: QueryDict 对象一个键可以保存多个值

  • get()方法

    • 根据键值

    • 如果一个键同时拥有多个值,将最后一个值

    • 如果键不存在则返回None值,可以设置返回自定义的默认值

      dict.get('键',默认值)
      
  • getlist()方法

    • 根据键多个值,值以列表返回

    • 如果键不存在则返回空列表[]

      dict.getlist('键',默认值)
      

四、通过request请求参数

1. 查询字符串

一、需求

URL地址 127.0.0.1:8000/news2?category=1&page=2 中的查询字符串的值

二、代码参考

# url配置





url(r'^news2$', views.news2),






# 视图函数





def news2(request):
    category = request.GET.get('category')
    page = request.GET.get('page')






    # ?category=1&page=2&a=3&a=4







    # a = request.GET.getlist('a')  # 一键多值通过 getlist 






    text = '查询字符串:<br/> category=%s, page=%s' % (category, page)
    return HttpResponse(text)

重 要:查询字符串不区分请求方式,即使客户端通过POST方式发起请求,依然可以通过request.GET请求中的查询字符串数据。

2. 请求体数据

请求体数据格式不固定,可以是表单类型字符串,可以是JSON字符串,可以是XML字符串,应区别对待。

可以发送请求体数据的请求方式有POSTPUTPATCHDELETE

Django对POSTPUTPATCHDELETE请求方式开启了CSRF安全防护,为方便测试,可以在settings.py文件中注释掉CSRF中间件,关闭CSRF防护

注释CSRF中间件

2.1 表单数据 Form Data (键值对)

前端发送的表单或键值对类型的请求体数据,可以通过request.POST属性

# url配置





url(r'^news3$', views.news3),






# 视图函数





def news3(request):
    category = request.POST.get('category')
    page = request.POST.get('page')






     # 一键多值通过从POST中用 getlist 







    # ?category=1&page=2&a=3&a=4







    # a = request.POST.getlist('a') 






    text = 'body中的键值对:<br/> category=%s, page=%s' % (category, page)
    return HttpResponse(text)

重 要:request.POST只能用来POST方式的请求体表单数据或键值对数据。如果为非post请求提交的请求体数据,或者是请求体数据类型为非表单或非键值对数据,则需要通过request.body属性提交的数据后,再自己手动解析

2.2 非表单类型 Non-Form Data

非表单类型的请求体数据,Django无法自动解析,可以通过request.body属性最原始的请求体数据,自己按照请求体格式(JSON、XML等)进行解析。request.body返回bytes类型。

例如请求体中的json数据: {"category": 1, "page": 2}

# url配置





url(r'^news4$', views.news4),

import json
def news4(request):





    # json字符串





    json_str = request.body
    json_str = json_str.decode()  # python3.6 无需执行此步






    # 解析json





    dict_data = json.loads(json_str)
    category = dict_data.get('category')
    page = dict_data.get('page')

    text = 'body中的json数据: category=%s, page=%s' % (category, page)
    return HttpResponse(text)

3. 请求头数据

可以通过 request.META 属性请求头headers中的数据, request.META 为字典类型

常见的请求头如:

  • CONTENT_LENGTH - The length of the request body (as a string).
  • CONTENT_TYPE - The MIME type of the request body.
  • HTTP_ACCEPT - Acceptable content types for the response.
  • HTTP_ACCEPT_ENCODING - Acceptable encodings for the response.
  • HTTP_ACCEPT_LANGUAGE - Acceptable languages for the response.
  • HTTP_HOST - The HTTP Host header sent by the client.
  • HTTP_REFERER - The referring page, if any.
  • HTTP_USER_AGENT - The client's user-agent string.
  • QUERY_STRING - The query string, as a single (unparsed) string.
  • REMOTE_ADDR - The IP address of the client.
  • REMOTE_HOST - The hostname of the client.
  • REMOTE_USER - The user authenticated by the Web server, if any.
  • REQUEST_METHOD - A string such as "GET" or "POST".
  • SERVER_NAME - The hostname of the server.
  • SERVER_PORT - The port of the server (as a string).

注意:

  • 自定义的请求头属性值时, 需 要添加前缀 HTTP_ 并转成大写,作为键来值

示例:

def news4(request):





    # 请求头数据:a=1&b=2





    print(request.META.get('HTTP_A'), request.META.get('HTTP_B'))

学习目标

  • 掌握request对象使用
  • 掌握response对象使用
  • 掌握Django中cookie的使用
  • 掌握Django中session的使用

未完待续 下一期下一章

完整笔记请看文章开头