一、请求与响应
视图函数
视图函数,简称视图,属于Django的视图层,默认定义在views.py文件中,是用来处理web请求信息以及返回响应信息的函数,所以研究视图函数只需熟练掌握两个对象即可:请求对象(HttpRequest)和响应对象(HttpResponse)
1、请求对象
当一个页面被请求时,django会创建一个包含本次请求原信息(如http协议请求报文中的请求行、首部信息、内容主体)的HttpRequest对象。
之后,django会找到匹配的视图,将该对象传给视图函数的第一个参数,约定俗称该参数名为request(类似于我们自定义框架的environ参数)。
在视图函数中,通过访问该对象的属性便可以提取http协议的请求数据
2、HttpRequest对象属性part1
python
一.HttpRequest.method
获取请求使用的方法(值为纯大写的字符串格式)。例如:"GET"、"POST"
应该通过该属性的值来判断请求方法
在视图函数中:
if request.method. == "GET":
...
if request.method == "POST":
...
二.HttpRequest.GET
值为一个类似于字典的QueryDict对象,封装了GET请求的所有参数,可通过HttpRequest.GET.get('键')获取相对应的值
在视图函数中:
request.GET.get('name')
三.HttpRequest.POST
值为一个类似于字典的QueryDict对象,封装了POST请求所包含的表单数据,可通过HttpRequest.POST.get('键')获取相对应的值
在视图函数中:
request.POST.get('name')
针对表单中checkbox类型的input标签、select标签提交的数据,键对应的值为多个,需要用:HttpRequest.POST.getlist("hobbies")获取存有多个值的列表,同理也有HttpRequest.GET.getlist("键")
针对有多个值的的情况,也可以用HttpRequest.GET.get("键"),默认会获取列表中的最后一个值
案例:
python
from django.urls import re_path
from app01 import views
urlpatterns = [
re_path(r'^login/$',views.login),
]
python
from django.shortcuts import render,HttpResponse
def login(request):
if request.method == 'GET':
# 当请求url为:http://127.0.0.1:8001/login/?a=1&b=2&c=3&c=4&c=5
# 请求方法是GET,?后的请求参数都存放于request.GET中
print(request.GET)
# 输出<QueryDict: {'a': ['1'], 'b': ['2'], 'c': ['3', '4', '5']}>
# 获取?后参数的方式为
a=request.GET.get('a') # 1
b=request.GET.get('b') # 2
c=request.GET.getlist('c') # ['3', '4', '5']
c1=request.GET.get('c') # 5
return render(request,'login.html')
elif request.method == 'POST':
# 在输入框内输入用户名egon、年龄18,选择爱好,点击提交
# 请求方法为POST,表单内的数据都会存放于request.POST中
print(request.POST)
# 输出<QueryDict: {..., 'name': ['egon'], 'age': ['18'], 'hobbies': ['music', 'read']}>
# 获取表单中数据的方式为
name=request.POST.get('name') # egon
age=request.POST.get('age') # 18
hobbies=request.POST.getlist('hobbies') # ['music', 'read']
return HttpResponse('提交成功')
在templates目录下新建login.html
python
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<!--
method="post"代表在提交表单时会以POST方法提交表单数据
action="/login/" 代表表单数据的提交地址为http://127.0.0.1:8001/login/,可以简写为action="/login/",或者action=""
-->
<form action="http://127.0.0.1:8001/login/" method="post">
{% csrf_token %} <!--强调:必须加上这一行,后续我们会详细介绍-->
<p>用户名:<input type="text" name="name"></p>
<p>年龄:<input type="text" name="age"></p>
<p>
爱好:
<input type="checkbox" name="hobbies" value="music">音乐
<input type="checkbox" name="hobbies" value="read">阅读
<input type="checkbox" name="hobbies" value="dancing">跳舞
</p>
<p><input type="submit" value="提交"></p>
</form>
</body>
</html>
3、HttpRequest对象属性part2
python
一.HttpRequest.path
获取url地址的路径部分,只包含路径部分
二.HttpRequest.get_full_path()
获取url地址的完整path,既包含路径又包含参数部分
如果请求地址是http://127.0.0.1:8001/order/?name=egon&age=10#_label3,
HttpRequest.path的值为"/order/"
HttpRequest.get_full_path()的值为"/order/?name=egon&age=10"
案例:
python
from django.urls import path,register_converter,re_path
from app01 import views
urlpatterns = [
re_path(r'^order',views.order),
]
python
from django.shortcuts import render,HttpResponse
# 针对请求的url地址:http://127.0.0.1:8001/order/?name=egon&age=10#_label3
# 从域名后的最后一个"/"开始到"?"为止是路径部分,即/order/
# 从"?"开始到"#"为止之间的部分为参数部分,即name=egon&age=10
def order(request):
print(request.path) # 结果为"/order/"
print(request.get_full_path()) # 结果为"/order/?name=egon&age=10"
return HttpResponse('order page')
4、HttpRequest对象属性part3
python
一.HttpRequest.META.get(...)
值为包含了HTTP协议的请求头数据的Python字典,字典中的key及期对应值的解释如下
CONTENT_LENGTH ------ 请求的正文的长度(是一个字符串)。
CONTENT_TYPE ------ 请求的正文的MIME类型。
HTTP_ACCEPT ------ 响应可接收的Content-Type。
HTTP_ACCEPT_ENCODING ------ 响应可接收的编码。
HTTP_ACCEPT_LANGUAGE ------ 响应可接收的语言。
HTTP_HOST ------ 客服端发送数据的目标主机与端口
HTTP_REFERER ------ Referring 页面。
HTTP_USER_AGENT ------ 客户端使用的软件版本信息
QUERY_STRING ------ 单个字符串形式的查询字符串(未解析过的形式)。
REMOTE_ADDR ------ 客户端的IP地址。
REMOTE_HOST ------ 客户端的主机名。
REMOTE_USER ------ 服务器认证后的用户。
REQUEST_METHOD ------ 一个字符串,例如"GET" 或"POST"。
SERVER_NAME ------ 服务器的主机名。
SERVER_PORT ------ 服务器的端口(是一个字符串)。
从上面可以看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 之外,HTTP协议的请求头数据转换为 META 的键时,
都会
1、将所有字母大写
2、将单词的连接符替换为下划线
3、加上前缀HTTP_。
所以,一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。
二、HttpRequest.encoding
一个字符串,表示提交的数据的编码方式(如果为 None 则表示使用 DEFAULT_CHARSET 的设置,默认为 'utf-8')。
这个属性是可写的,你可以修改它来修改访问表单数据使用的编码。
接下来对属性的任何访问(例如从 GET 或 POST 中读取数据)将使用新的 encoding 值。
如果你知道表单数据的编码不是 DEFAULT_CHARSET ,则使用它。
三、HttpRequest.scheme
表示请求方案的字符串(通常为http或https)
四、其他
HttpRequest还有很多其他重要属性,比如HttpRequest.body,待我们讲到专门的知识点时再专门详细讲解
5、响应对象
请求对象HttpRequest是由django为我们创建好的,直接使用即可,而响应对象则需要我们负责创建。我们编写的每个视图都应该返回一个HttpResponse对象,响应可以是一个网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。用来返回响应对象的常用类如下
python
from django.shortcuts import HttpResponse
from django.shortcuts import redirect
from django.shortcuts import render
from django.http importJsonResponse
6、HttpResponse
python
from django.http import HttpResponse
response = HttpResponse("Here's the text of the Web page.")
response = HttpResponse("Text only, please.", content_type="text/plain")
'''
ps:Content-Type用于指定响应体的MIME类型
MIME类型:
mime类型是多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开
MIME 类型有非常多种,一般常见的有:
text/html:浏览器在获取到这种文件时会自动调用html的解析器对文件进行相应的处理。
text/plain:意思是将文件设置为纯文本的形式,浏览器在获取到这种文件时并不会对其进行处理。
image/jpeg:JPEG格式的图片
image/gif:GIF格式的图片
video/quicktime:Apple 的 QuickTime 电影
application/vnd.ms-powerpoint:微软的powerpoint文件
'''
7、render
python
def render(request, template_name, context=None, content_type=None, status=None, using=None):
"""
Return a HttpResponse whose content is filled with the result of calling
django.template.loader.render_to_string() with the passed arguments.
"""
content = loader.render_to_string(template_name, context, request, using=using)
return HttpResponse(content, content_type, status)
参数:
1、request:用于生成响应的请求对象,固定必须传入的第一个参数
2、template_name:要使用的模板的完整名称,必须传入,render默认会去templates目录下查找模板文件
3、context:可选参数,可以传入一个字典用来替换模块文件中的变量,默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。
4、content_type:生成的文档要使用的MIME类型。默认为 DEFAULT_CONTENT_TYPE 设置的值。默认为'text/html'
5、status:响应的状态码。默认为200。
6、using: 用于加载模板的模板引擎的名称。
8、redirect
python
返回重定向对象,返回的状态码为302,第一个参数用来指定浏览器重定向的地址,可以是
#1、一个完全标准的URL地址,如'https://www.yahoo.com/search/'
#2、也可以是一个没有域名的绝对路径,如'/search/'
#3、或者是一个没有域名的相对路径,如'search/',与1、2直接跳转到指定的绝对路径不同,相对路径需要先与当前路径进行拼后才能跳转,例如:如果当前路径为http://127.0.0.1:8080/index/,拼接后的路径为http://127.0.0.1:8080/index/search/
# ps:redirect重定向等同于下述操作
def index(request):
response=HttpResponse()
response.status_code=302 # 必须设置响应的状态码,才能重定向
response['Location']='/register/' # 设置响应头
return response
9、JsonResponse
向前端返回一个json格式字符串的两种方
方式一:
python
import json
def my_view(request):
data=['egon','kevin']
return HttpResponse(json.dumps(data) )
方式二:
python
from django.http import JsonResponse
def my_view(request):
data=['egon','kevin']
return JsonResponse(data,safe=False)
#默认safe=True代表只能序列化字典对象,safe=False代表可以序列化字典以外的对象