博客链接 https://blog.csdn.net/cPen_web
视频链接 https://www.bilibili.com/video/BV1vK4y1o7jH
GET请求和POST请求
定义
- 无论是GET还是POST,统一都由视图函数接收请求,通过判断request.method区分具体的请求动作
- 样例:
if requests.method == 'GET':
处理GET请求时的业务逻辑
elif requests.method == 'POST':
处理POST请求的业务逻辑
else:
其他请求业务逻辑
- 演示
# <项目同名文件夹下>/views.py
def test_get_post(request):
if request.method == 'GET':
pass
elif request.method == 'POST':
#处理用户提交数据
pass
else:
pass
return HttpResponse('--test get post is ok--')
GET处理
-
GET请求动作,一般用于向服务器
获取数据
-
能够产生GET请求的场景:
-- 浏览器地址栏中输入URL,回车后
-- <a href
="地址?参数=值&参数=值">
--form表单
中的method为get
-
GET请求方式中,如果有数据需要传递给服务器,通常会用
查询字符串(Query String)
传递【注意:不要传递敏感数据
】 -
URL格式:xxx?参数名1=值1&参数名2=值2...
-- 如:http://127.0.0.1:8000/page1?a=100&b=200
-
服务器端接收参数
-- 获取客户端请求GET请求提交的数据 -
方法示例:
request.GET['参数名'] # QueryDict
request.GET.get('参数名', '默认值')
request.GET.getlist('参数名')
# mypage?a=100&b=200&c=300&b=400
# request.GET=QueryDict({'a': ['100'], 'b': ['200', '400'], 'c': ['300']})
# a = request.GET['a']
# b = request.GET['b'] # Error
- 演示
http://127.0.0.1:8000/test_get_post?a=400
--test get post is ok--
# 终端
<QueryDict: {'a': ['400', '200', '100']}>
100
['400', '200', '100']
no c
# <项目同名文件夹下>/urls.py
urlpatterns = [
...
path('test_get_post', views.test_get_post)
]
# <项目同名文件夹下>/views.py
def test_get_post(request):
if request.method == 'GET':
print(request.GET)
print(request.GET['a'])
# 问卷调查 = form get 兴趣爱好 - 复选框
print(request.GET.getlist('a'))
print(request.GET.get('c', 'no c'))
elif request.method == 'POST':
#处理用户提交数据
pass
else:
pass
return HttpResponse('--test get post is ok--')
- 思考
思考:之前的计算器功能,能否拿查询字符串做?
-- http://127.0.0.1:8000/整数/操作符/整数
-- http://127.0.0.1:8000/cal?x=10&y=20&op=add
POST处理
- POST请求动作,一般用于
向服务器提交大量/隐私数据
- 客户端通过表单等POST请求将数据传递给服务器端,如:
- 服务器端
接收参数
通过request.method来判断是否为POST请求,如:
if request.method == 'POST':
处理POST请求的数据并响应
else:
处理非POST请求的响应
- 使用post方式接收客户端数据
request.POST['参数名'] # request.POST 绑定QueryDict
request.POST.get('参数名', '')
request.POST.getlist('参数名')
取消csrf验证,否则Django将会拒绝客户端发来的POST请求,报403响应
# 取消csrf验证
- 禁止掉settings.py中MIDDLEWARE中的CsrfviewsMiddleWare的中间件
MIDDLEWARE = [
...
# 'django.middleware.csrf.CsrfViewMiddleware',
...
]
- 演示
http://127.0.0.1:8000/test_get_post
post is ok
# 终端
uname is cpen
# <项目同名文件夹下>/urls.py
urlpatterns = [
...
path('test_get_post', views.test_get_post)
]
# <项目同名文件夹下>/views.py
POST_FORM = '''
<form method='post' action='/test_get_post'>
用户名: <input type='text' name='uname'>
<input type='submit' value='提交'>
</form>
'''
def test_get_post(request):
if request.method == 'GET':
return HttpResponse(POST_FORM)
...
- 小节
Django处理GET请求
查询字符串 - 少量数据传递
Django处理POST请求
专用于浏览器提交数据
Django的设计模式及模板层
MVC和MTV
传统的MVC
MVC代表Model-View-Controller
(模型-视图-控制器)模式。
√ M模型层(Model)
,主要用于对数据库层的封装
√ V视图层(View)
,用于向用户展示结果(WHAT + HOW)
√ C控制(Controller)
,用于处理请求、获取数据、返回结果(重要)
作用:降低模块间的耦合度(解耦)
Django的MTV模式
MTV代表Model-Template-View
(模型-模板-视图)模式。
√ M模型层(Model)
负责与数据库交互
√ T模板层(Template)
负责呈现内容到浏览器(HOW)
√ V视图层(View)是核心
,负责接收请求、获取数据、返回结果(WHAT)
作用:降低模块间的耦合度(解耦)
附:MTV-诞生记
模板层
什么是模板
- 模板是可以根据
字典
数据动态变化的html网页
- 模板可以
根据视图中传递的字典数据动态生成相应的HTML网页
模板配置
- 创建模板文件夹
<项目名>/templates
- 在
settings.py
中TEMPLATES
配置项
- BACKEND:指定模板的引擎
-
DIRS
:模板的搜索目录(可以是一个或多个) - APP_DIRS:是否要在应用中的templates文件夹中搜索模板文件
- OPTIONS:有关模板的选项
-
配置项中 需要修改部分
设置DIRS -'DIRS': [os.path.join(BASE_DIR, 'templates')],
-
演示
# <项目同名文件夹下>/settings.py
TEMPLATES = [
{
...
'DIRS': [os.path.join(BASE_DIR, 'templates')],
...
模板的加载方式
- 方案1 - 通过loader获取模板,通过HttpResponse进行响应(特点:麻烦)
- 在视图函数中:
from django.template import loader
# 1.通过 loader 加载模板
t = loader.get_template("模板文件名")
# 2.将 t 转换成 HTML 字符串
html = t.reader(字典数据)
# 3.用响应对象将转换的字符串内容返回给浏览器
return HttpResponse(html)
- 演示
http://127.0.0.1:8000/test_html
# <项目同名文件夹下>/urls.py
urlpatterns = [
...
path('test_html', views.test_html)
]
# <项目同名文件夹下>/views.py
def test_html(request):
from django.template import loader
t = loader.get_template('test_html.html')
html = t.render()
return HttpResponse(html)
# <项目文件夹下>/templates/test_html.html
<h3>我是模板层的~~~~</h3>
- 方案2 - 通过render() 直接加载并响应模板(特点:方便,大量使用这种)
- 在视图函数中:
from django.shortcuts import render
return render(request, '模板文件名', 字典数据)
- 演示
http://127.0.0.1:8000/test_html
<项目同名文件夹下>/views.py
def test_html(request):
# 方案2
from django.shortcuts import render
return render(request, 'test_html.html')
视图层与模板层之间的交互
- 视图函数中可以将Python变量封装到
字典
中传递到模板
- 样例:
def xxx_view(request):
dic = {
"变量1": "值1",
"变量2": "值2",
}
return render(request, 'xxx.html', dic)
- 模板中,我们可以用
{{ 变量名 }}
的语法 调用视图传进来的变量
- 演示
http://127.0.0.1:8000/test_html
# <项目同名文件夹下>/urls.py
urlpatterns = [
...
path('test_html', views.test_html)
]
# <项目同名文件夹下>/views.py
def test_html(request):
from django.shortcuts import render
dic = {'username': 'peng', 'age': 23}
return render(request, 'test_html.html', dic)
# <项目文件夹下>/templates/test_html.html
<h3>{{ username }}是模板层的~~~~</h3>