一、请求request

前端向后端传递参数有几种方式?

  • 提取URL的特定部分,如/weather/beijing/2018,可以在服务器端的路由中用正则表达式截取; "http://127.0.0.1/weather/beijing/2018"
  • 查询字符串(query string),形如key1=value1&key2=value2; "http://127.0.0.1/weather/?area=beijing&year=2018"
  • 请求体(body)中发送的数据,比如表单数据、json、xml; "POST方法的请求体中"
  • 在http报文的头(header)中。

1.URL路径传参

任何一种请求方式都可以通过路径传参 POST  GET PUT  DELETE 

命名参数按定义顺序传递,如

urlpatterns = [
url(r'^weather/([a-z]+)/(\d{4})/$', views.weather)
] def weather(request, city, year):
return HttpResponse("您查询的城市是%s年份是%s" % (city, year))

直接在url路径里写入参数,后端在匹配路由的时候,通过正则的方式提取到参数,在视图函数中,按照顺序来传入参数

命名参数按名字传递,如

urlpatterns = [
url(r'^weather/(?P<city>[a-z]+)/(?P<year>\d{4})/$', views.weather),
] def weather(request, year, city):
return HttpResponse("您查询的城市是%s年份是%s" % (city, year))

命名参数在往视图函数中传递的时候不用在意传入的顺序,但是传入的参数名字要和正则里保持一致

2.查询字符串传参

获取请求路径中的查询字符串参数(形如?k1=v1&k2=v2),可以通过request.GET属性获取,返回QueryDict对象。

# 请求地址 http://127.0.0.1:8000/qs/?a=aaa&b=bbb&a=a2222
def qs(request):
query_dict = request.GET
a = query_dict.get('a')
b = query_dict.get('b')
alist = query_dict.getlist('a') print(a, b, alist)
# a2222 bbb ['aaa', 'a2222']
return HttpResponse("OK") # url配置
urlpatterns = [
url(r'^qs/$', views.qs),
]

可以看出,当查询字符串中有多个相同名字的参数时,如果调用get方法,获取的是最后一个的值,getlist方法返回的是一个列表

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

使用postman来进行post请求,需要先在settings配置文件中关闭CSRF中间件

3.请求体传参

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

可以发送请求体数据的请求方式有POST、PUT、PATCH、DELETE

Django默认开启了CSRF防护,会对上述请求方式进行CSRF防护验证,在测试时可以关闭CSRF防护机制,方法为在settings.py文件中注释掉CSRF中间件

3.1表单类型 Form Data

前端发送的表单类型的请求体数据,可以通过request.POST属性获取,返回QueryDict对象。

重要:request.POST只能用来获取POST方式的请求体表单数据。

演示

def qs(request):
query_dict = request.GET
a = query_dict.get('a')
b = query_dict.get('b')
alist = query_dict.getlist('a') print("查询字符串是分别是%s,%s,%s" % (a, b, alist)) post_dict = request.POST c_post = post_dict.get('c')
d_post = post_dict.get('d')
c_list = post_dict.getlist('c')
print("表单数据是分别是%s,%s,%s" % (c_post, d_post, c_list)) return HttpResponse("OK")

同时可以用request.GET和request.POST

3.2非表单类型

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

def json_view(request):
json_bytes = request.body req_dict = json.loads(json_bytes.decode()) a = req_dict.get("a")
b = req_dict.get("b") return HttpResponse("获取到a是%s,b是%s" % (a, b))

python3.6版本以后,json.loads()既能接受bytes类型,也能接受str类型,但是3.6之前的版本,只能接受str类型,所以如果是python3.6以前的版本,decode()一下就好

3.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 get_headers(request):
print(request.META['CONTENT_TYPE'])
return HttpResponse('OK')

4.其他常用HttpRequest对象属性

  • method:一个字符串,表示请求使用的HTTP方法,常用值包括:'GET'、'POST'。
  • user:请求的用户对象。
  • path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。
  • encoding:一个字符串,表示提交的数据的编码方式。
    • 如果为None则表示使用浏览器的默认设置,一般为utf-8。
    • 这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。
  • FILES:一个类似于字典的对象,包含所有的上传文件。

二、响应

视图在接收请求并处理后,必须返回HttpResponse对象或子对象。HttpRequest对象由Django创建HttpResponse对象由开发人员创建

1.HttpResponse

可以使用django.http.HttpResponse来构造响应对象。

HttpResponse(content=响应体, content_type=响应体数据类型, status=状态码)

演示

def response(request):

    s = '{"name": "zhangsan", "age": 21}'

    return HttpResponse(s, content_type='application/json', status=200)

# url配置
urlpatterns = [
url(r'^resp$', views.response),
]

也可通过HttpResponse对象属性来设置响应体、状态码:

  • content:表示返回的内容。
  • status_code:返回的HTTP响应状态码。
def response(request):

    resp = HttpResponse()
resp.content = "hello world!"
resp.status_code = 200
resp["It"] = "hello" return resp

其实就是在实例化对象之后,再设置响应体和状态码

设置响应头的方法就是 resp["It"] = "hello"

HttpResponse子类

Django提供了一系列HttpResponse的子类,可以快速设置状态码

  • HttpResponseRedirect 301
  • HttpResponsePermanentRedirect 302
  • HttpResponseNotModified 304
  • HttpResponseBadRequest 400
  • HttpResponseNotFound 404
  • HttpResponseForbidden 403
  • HttpResponseNotAllowed 405
  • HttpResponseGone 410
  • HttpResponseServerError 500

JsonResponse

若要返回json数据,可以使用JsonResponse来构造响应对象,作用:

  • 帮助我们将数据转换为json字符串
  • 设置响应头Content-Type为 application/json
from django.http import JsonResponse

def demo_view(request):
return JsonResponse({'city': 'beijing', 'subject': 'python'})

redirect重定向

from django.shortcuts import redirect

def demo_view(request):
return redirect('/index.html')

Cookie

Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。Cookie最早是网景公司的前雇员Lou Montulli在1993年3月的发明。Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)。Cookie名称和值可以由服务器端开发自己定义,这样服务器可以知道该用户是否是合法用户以及是否需要重新登录等。服务器可以利用Cookies包含信息的任意性来筛选并经常性维护这些信息,以判断在HTTP传输中的状态。Cookies最典型记住用户名。

Cookie是存储在浏览器中的一段纯文本信息,建议不要存储敏感信息如密码,因为电脑上的浏览器可能被其它人使用。

Cookie的特点

  • Cookie以键值对的格式进行信息的存储。
  • Cookie基于域名安全,不同域名的Cookie是不能互相访问的,如访问qq.com时向浏览器中写了Cookie信息,使用同一浏览器访问baidu.com时,无法访问到qq.com写的Cookie信息。
  • 当浏览器请求某网站时,会将浏览器存储的跟网站相关的所有Cookie信息提交给网站服务器。

设置Cookie

可以通过HttpResponse对象中的set_cookie方法来设置cookie。

HttpResponse.set_cookie(cookie名, value=cookie值, max_age=cookie有效期)
  • max_age 单位为秒,默认为None。如果是临时cookie,可将max_age设置为None。

示例:

def set_cookie(request):
resp = HttpResponse("设置cookie")
resp.set_cookie("name","zhangsan") # 这是一个临时的cookie,退出浏览器就没了
resp.set_cookie("name2", "lisi", max_age=3600) # 有效期一个小时的cookie
return resp # url配置 urlpatterns = [
url(r'^cookie/$', views.set_cookie),
]

效果

上面的这个是临时cookie

上面的这个是有效期一小时的cookie

读取Cookie

可以通过HttpRequest对象的COOKIES属性来读取本次请求携带的cookie值。request.COOKIES为字典类型。

def look(request):
name2 = request.COOKIES.get("name2")
return HttpResponse("name2的值是%s" % name2)

效果

这时候去看还有没有name这个cookie

发现只有这两个

Session

启用Session

Django项目默认启用Session。

可以在settings.py文件中查看,如图所示

session是什么意思

cookie是存在前端的,session是存在后端的,那么session是存在哪呢

session可以存放在数据库中、本地缓存(程序的运行内存中,全局变量)、文件里、redis里

Django的session存储方式

在settings.py文件中,可以设置session数据的存储方式,可以保存在数据库、本地缓存等。

数据库

存储在数据库中,如下设置可以写,也可以不写,这是默认存储方式。

SESSION_ENGINE='django.contrib.sessions.backends.db'

如果存储在数据库中,需要在项INSTALLED_APPS中安装Session应用。

数据库中的表如图所示

表结构是

由表结构可知,操作Session包括三个数据:键,值,过期时间。

本地缓存

存储在本机内存中,如果丢失则不能找回,比数据库的方式读写更快。

SESSION_ENGINE='django.contrib.sessions.backends.cache'

存储在本机内存中的话,如果程序重新启动,那么之前的session就都没了

混合存储

优先从本机内存中存取,如果没有则从数据库中存取。

SESSION_ENGINE='django.contrib.sessions.backends.cached_db'

本地缓存跨机问题

服务器肯定不只是一个服务器,如果使用本地存储来存放session的话,用户在第一台服务器登陆,然后session存储在第一台服务器了,如果第二次访问的时候,nginx把用户分到了第二台服务器上,那么第二台服务器上没有存储用户的session,会造成用户还需要登陆,所以为了解决这个问题,就需要使用redis来存储session

使用django-redis保存session

在redis中保存session,需要引入第三方扩展,我们可以使用django-redis来解决。

安装扩展

pip install django-redis

在settings.py文件中做如下设置

CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"

上面的配置信息放在settings文件的最后

设置session

def session(request):
request.session['name'] = "zhangsan"
request.session['age'] = 21
return HttpResponse("设置session成功") # url配置
urlpatterns = [
url(r'^session$', views.session),
]

发现有数据,这个key是django-redis自动生成的。

Session操作

通过HttpRequest对象的session属性进行会话的读写操作。

1) 以键值对的格式写session。

request.session['键']=值

2)根据键读取值。

request.session.get('键',默认值)

3)清除所有session,在存储中删除值部分。

request.session.clear()

4)清除session数据,在存储中删除session的整条数据。

request.session.flush()

5)删除session中的指定键及值,在存储中只删除某个键及对应的值。

del request.session['键']

6)设置session的有效期

request.session.set_expiry(value)
  • 如果value是一个整数,session将在value秒没有活动后过期。
  • 如果value为0,那么用户session的Cookie将在用户的浏览器关闭时过期。
  • 如果value为None,那么session有效期将采用系统默认值,默认为两周,可以通过在settings.py中设置SESSION_COOKIE_AGE来设置全局默认值。

django复习-3-请求与响应的更多相关文章

  1. Django整理(五) - 请求与响应 - request对象

    请求对象 一.客户端传参的几种方式 1. 通过URL路径(path)传递,例如:http://127.0.0.1:8000/news/1/2,两个参数:id和page 2. 通过 query stri ...

  2. django rest-framework 2.请求和响应

    一.请求对象 REST 框架引入Request来扩展常规的HttpRequest,并提供了更灵活的请求解析.Request对象的核心功能是request.data属性. 导入方式: from rest ...

  3. Django底层剖析之一次请求到响应的整个流程

    As we all know,所有的Web应用,其本质上其实就是一个socket服务端,而用户的浏览器就是一个socket客户端. #!/usr/bin/env python #coding:utf- ...

  4. Django编写RESTful API(二):请求和响应

    欢迎访问我的个人网站:www.comingnext.cn 前言 在上一篇文章,已经实现了访问指定URL就返回了指定的数据,这也体现了RESTful API的一个理念,每一个URL代表着一个资源.当然我 ...

  5. Django REST FrameWork中文教程2:请求和响应

    从这一点开始,我们将真正开始覆盖REST框架的核心.我们来介绍几个基本的构建块. 请求对象REST框架引入了Request扩展常规的对象HttpRequest,并提供更灵活的请求解析.Request对 ...

  6. django请求和响应

    本文转载自https://blog.csdn.net/xiaogeldx/article/details/88096341 HttpRequest对象 服务器接收到http协议的请求后,会根据报文创建 ...

  7. Django 学习第九天——请求与响应

    一.HttpRequest 对象: 服务器接收到http协议的请求后,会根据报文创建 HttpRequest 对象视图函数的第一个参数是HttpRequest 对象再django.http 模块中定义 ...

  8. django 请求与响应

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. python的Web框架,Django框架中的请求与响应

    请求与响应 简单流程图 我们先来了解一个请求与响应的大概流程  视图函数接受到的request到底是个什么对象呢? 服务器接收到http协议的请求后,会根据报文创建HttpRequest对象视图函数的 ...

随机推荐

  1. POJ 1740(构造博弈)

    题目链接: https://cn.vjudge.net/problem/POJ-1740 题目描述: Alice and Bob decide to play a new stone game.At ...

  2. Core Animation之基础介绍

    了解了图层,现在学习核心动画. Core Animation是直接作用在CALayer上的,并非UIView. 一.使用步骤 1.使用它需要先添加QuartzCore.framework框架和引入主头 ...

  3. .29-浅析webpack源码之doResolve事件流(1)

    在上一节中,最后返回了一个resolver,本质上就是一个Resolver对象: resolver = new Resolver(fileSystem); 这个对象的构造函数非常简单,只是简单的继承了 ...

  4. Excel上传并读取数据

    最近一段时间,维护一个旧系统,其中有一个功能,是把Excel上传,并读取数据进行维护,然后转插入至SQL数据库中.下面Insus.NET使用asp.net 标准上传控件: <asp:FileUp ...

  5. Visual Studio 监视与快速监视即时窗口没有智能提示

    工具->选项->文本编辑器->C# 将 自动列出成员 参数信息 都勾选上

  6. 自动生成编号(B开头后跟6位,数据库查询不重复)

    private string GetAccountNo() { try { string shortName="B"; "; //查询数据库 7位且包含“B” & ...

  7. 自己写一个java的mvc框架吧(五)

    自己写一个mvc框架吧(五) 给框架添加注解的支持 一段废话 上一章本来是说这一章要写视图处理的部分,但是由于我在测试代码的时候需要频繁的修改配置文件,太麻烦了.所以这一章先把支持注解的功能加上,这样 ...

  8. Java - 数组解析

    java提高篇(十八)-----数组之一:认识JAVA数组 一.什么是数组 数组?什么是数组?在我印象中的数组是应该这样的:通过new关键字创建并组装他们,通过使用整形索引值访问它的元素,并且它的尺寸 ...

  9. 反射和动态加载bean 完成 通用servie

    最近我们部门有个小项目,用来管理这个公司所有项目用到的代码表,例如国家代码.行政区划代码等.这个项目的功能其实很少,就是简单的修改.查询.新增和逻辑删除.但是为每张表都写一套增删改查的页面和一套ser ...

  10. CentOS7上搭建LDAP-PDC并且将windows 2008 R2加入LDAP-PDC域

    由于测试原因,要涉及到将windows机器加入到ldap域,所以查看各种文档进行ldap-pdc域的搭建,并成功将windows 2008r2加入到ldap-pdc域中.下面简单记录一下搭建过程 Li ...