请求:
在解释Django中的服务器获取参数之前,先说明一下,前端通过HTTP协议返回给咱们后端的传递参数的方式,有哪几种?
①提取URL的特定部分,如/weather/beijing/2018,可以在服务器端的路由中用正则表达式截取;
②查询字符串(query string),形如key1=value1&key2=value2;
③请求体(body)中发送的数据,比如表单数据、json、xml;
④在http报文的头(header)中。
1.从请求行中获取参数
①.未命名参数
**未命名参数的获取方式是通过【顺序传递】的方式获取。
子应用名称:–> testfile
主路由配置:–> urlpatterns 增加 url(r’^testfile/’, include(‘testfile.urls’))
本篇解说,上面这两个配置不变
#子应用中的路由设置:
url(r'^nonname/([a-z]+)(\d+)/$', views.nonname)
# 视图函数:
def nonname(request, name, age):
print('%s的年龄是%s' % (name, age))
return HttpResponse("This is nonname")
现在,通过浏览器访问,浏览器访问的链接是:
http://127.0.0.1:8000/testfile/nonname/xiaohua18/
我们从终端得到的结果是:
xiaohua的年龄是18
②.命名参数
**命名参数的参数获取方式,是根据【命名传参】,也叫【关键字传参】;
子应用中路由的配置:
url(r'^hometown/(?P<name>([a-z]+))/(?P<city>([a-z]+))', views.hometown)
# 视图函数
def hometown(request, name, city):
print('My name is %s, I am come form %s' % (name, city))
return HttpResponse('命名参数')
浏览器访问的url:
http://127.0.0.1:8000/testfile/hometown/xiaohua/beijing
终端输出结果是:
My name is xiaohua, I am come form beijing
③.查询字符串
**获取请求路径中的查询字符串参数,可以通过request.GET属性获取,返回QueryDict对象
子应用中的路由:
url(r'^search/', views.search)
视图函数:
def search(request):
name = request.GET.get('name')
age = request.GET.get('age')
names = request.GET.getlist('name')
print(name)
print(age)
print(names)
return HttpResponse('字符串查询')
浏览器的访问url:
http://127.0.0.1:8000/testfile/search/?name=xiaohua&age=18&name=xiaohong
终端输出结果:
xiaohong
18
[‘xiaohua’, ‘xiaohong’]
注意:
这里使用的GET,并不是我们理解的GET请求方式,只是一种属性,其实我们在通过查询字符串获取参数时,不管时GET还是POST请求,都是可以的;这样一来,也说明了,我们用的 GET 获取参数和 GET请求 没有多大关系。
拓展:关于Django中的QueryDict:
2.从请求体中获取参数
Django默认开启了CSRF防护,会对上述请求方式进行CSRF防护验证,在测试时可以关闭CSRF防护机制,方法为在settings.py文件中注释掉CSRF中间件,如:
①.表单类型
从请求体获取数据,我们现在在没有项目的支持下,可以借助postman来模拟浏览器发起请求;
子应用中的路由:
url(r'^formbody/', views.formbody)
视图函数:
def formbody(request):
name = request.POST.get("name")
age = request.POST.get('age')
print(name, age)
return HttpResponse('请求体-表单类型')
Postman相关数据:
图中用荧光笔标黄的地方,在数据测试时候,注意不要弄错。
终端结果:
xiaohong
18
②.非表单类型 关于非表单类型,这里为了方便操作和便于观察,我们可以使用json数据;
子应用路由配置:
url(r'^jsons/', views.jsons)
# 视图函数配置:
def jsons(request):
json_byte = request.body
print(json_byte)
json_str = json_byte.decode()
print(json_str)
json_dict = json.loads(json_str)
name = json_dict['name']
age = json_dict['age']
print(name, age)
return HttpResponse('请求体-json类型')
运行结果:
b’{“name”:“xiaohua”, “age”:18}’
{“name”:“xiaohua”, “age”:18}
xiaohua 18
Postman操作截图:
**注意:**json的数据中,所有的字符串必须是用“”双引号括起来,单引号是会报错的哦
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).
下面举一个栗子:
#我的视图函数是这样的:
def dada(request):
aa = request.META['CONTENT_TYPE']
print(aa)
return HttpResponse('haha')
#浏览器访问的url是这样的:
http://127.0.0.1:8000/testfile/dada/
然后,从终端获取的结果是:
text/plain
还有一些其他的HttpRequest对象属性:
method:一个字符串,表示请求使用的HTTP方法,常用值包括:‘GET’、‘POST’。
user:请求的用户对象。
path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。
encoding:一个字符串,表示提交的数据的编码方式。
如果为None则表示使用浏览器的默认设置,一般为utf-8。
这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。
FILES:一个类似于字典的对象,包含所有的上传文件。
再次举个栗子:
def didi(request):
print(request.method)
print(request.user)
print(request.path)
return HttpResponse('haha')
终端运行结果:
GET
AnonymousUser
/testfile/didi/
响应:
视图在接收请求并处理后,必须返回HttpResponse对象或子对象。HttpRequest对象由Django创建,HttpResponse对象由开发人员创建。
构造响应对象有如下几个方式。
1. HttpResponse:
可以使用django.http.HttpResponse来构造响应对象
HttpResponse(content=响应体, content_type=响应体数据类型, status=状态码)
也就是说,我们可以通过设置HttpResponse对象的属性,来设置响应数据。
demo如下:
def didi(request):
return HttpResponse("didi", status=555)
通过Postman获取的结果如下:
响应头里面的状态码是555,响应体的内容是didi
当然,响应头可以直接将HttpResponse对象当做字典进行响应头键值对的设置:
def didi(request):
response = HttpResponse('itcast python')
response.status_code = 400
response['Itcast'] = 'Python'
response['Content-Type'] = 'application/json'
return response
2. HttpResponse子类:
Django提供了一系列HttpResponse的子类,可以快速设置状态码
HttpResponseRedirect 301
HttpResponsePermanentRedirect 302
HttpResponseNotModified 304
HttpResponseBadRequest 400
HttpResponseNotFound 404
HttpResponseForbidden 403
HttpResponseNotAllowed 405
HttpResponseGone 410
HttpResponseServerError 500
3.JsonResponse:
若要返回json数据,可以使用JsonResponse来构造响应对象
作用:
1.帮助我们将数据转换为json字符串
2.设置响应头Content-Type为 application/json
from django.http import JsonResponse
def demo_view(request):
return JsonResponse({'city': 'beijing', 'subject': 'python'})
我们可以直接将字典放在响应体中进行返回,因为在JsonResponse中,已经将数据转为json格式了。
# JsonResponse类中部分源代码
if json_dumps_params is None:
json_dumps_params = {}
kwargs.setdefault('content_type', 'application/json')
data = json.dumps(data, cls=encoder, **json_dumps_params)
super(JsonResponse, self).__init__(content=data, **kwargs)