当你考虑开发现代化、高效且可扩展的网站和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 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),
]
#x27;, 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 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),
]
#x27;, 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# 项目的urls.py
urlpatterns = [
url(r'^index$', views.index),
]
#x27;, views.index),
]
配 置方式二: 在项目和应用的urls.py中都进行配置
# 项目的urls.py
urlpatterns = [
# 此处正则配置^, 表示任务的字符串都可以匹配成功
url(r'^', include('users.urls')),
]
# 应用的urls.py
urlpatterns = [
url(r'^index# 项目的urls.py
urlpatterns = [
# 此处正则配置^, 表示任务的字符串都可以匹配成功
url(r'^', include('users.urls')),
]
# 应用的urls.py
urlpatterns = [
url(r'^index$', views.index),
]
#x27;, 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+)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))
#x27;, 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+)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))
#x27;, users.views.news),
# 在 users/views.py 中定义
def news(request, category, page):
return HttpResponse(显示新闻:%s %s % (category, page))
请求与响应
学习目标
- 掌握request对象使用
- 掌握response对象使用
- 掌握Django中cookie的使用
- 掌握Django中session的使用
请求对象
一、客户端传参的几种方式
-
通过 URL 路径(
path
)传递,例如:127.0.0.1:8000/news/1/2
,两个参数:新闻类别id
和页码
-
通过
query string 查询字符串
传递1. 例如:`127.0.0.1:8000/news?category=1&page=2`
2. 关于URL格式: `schema://host[:port][path][?query-string][#anchor]` -
通过
body 请求体
传递,又可根据传递的数据格式,分为:-
键值对:
category=1&page=2
2. 表单数据:
3. 非表单数据(json, xml){"category": 1, "page": 2}
<news> <category>1</category> <page>2</page> </news>
-
-
通过
http
协议请求头(header
)传递
二、HttpRequest对象
一、Django请求和响应过程:
二、request对象常用属性:
Attribute | Description |
---|---|
path | 请求页面的全路径,不包括域名端口参数。例如: /users/index |
method | 一个全大写的字符串,表示请求中使用的HTTP方法,常用值:GET , POST ,DELETE ,PUT 等。以下三种为 |
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.SessionStore
。
Django
提供了 session
模块,默认就会开启用来保存 session
数据
三、QueryDict对象
-
所在的包:
django.http.QueryDict
-
HttpRequest
对象中的GET
和POST
属性 都是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# 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)
#x27;, 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字符串,应区别对待。
可以发送请求体数据的请求方式有POST
、PUT
、PATCH
、DELETE
。
Django对POST
、PUT
、PATCH
、DELETE
请求方式开启了CSRF安全防护,为方便测试,可以在settings.py
文件中注释掉CSRF中间件,关闭CSRF
防护
2.1 表单数据 Form Data (键值对)
前端发送的表单或键值对类型的请求体数据,可以通过request.POST属性
# url配置
url(r'^news3# 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)
#x27;, 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# 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)
#x27;, 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的使用