# 1. http请求响应
drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作。所以在django原有的django.views.View类基础上,drf封装了多个视图子类出来提供给我们使用。 Django REST framwork 提供的视图的主要作用: - 控制序列化器的执行(检验、保存、转换数据) - 控制数据库查询的执行 - 调用请求类和响应类[这两个类也是由drf帮我们再次扩展了一些功能类。]
为了方便我们学习,所以先创建一个子应用req
```python python manage.py startapp req ``` 注册子引用: ```python INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'students', 'sers', # 序列化器 "school", # 序列化器嵌套 'req', # 请求与响应 ] ``` 注册路由 ```python # 子应用路由 from django.urls import path from . import views urlpatterns = [ ] # 总路由 from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('students/', include("students.urls")), path('sers/', include("sers.urls")), path('school/', include("school.urls")), path("req/", include("req.urls")), ]
## 1.1. 请求与响应
内容协商:drf在django原有的基础上,新增了一个request对象继承到了APIVIew视图类,并在django原有的HttpResponse响应类的基础上实现了一个子类rest_framework.response.Response响应类。这两个类,都是基于内容协商来完成数据的格式转换的。 request->parser解析类->识别客户端请求头中的Content-Type来完成数据转换成->类字典(QueryDict,字典的子类) response->renderer渲染类->识别客户端请求头的"Accept"来提取客户端期望的返回数据格式,-> 转换成客户端的期望格式数据
### 1.1.1 Request
REST framework 传入视图的request对象不再是Django默认的HttpRequest对象,而是REST framework提供的扩展了HttpRequest类的**Request**类的对象。 REST framework 提供了**Parser**解析器,在接收到请求后会自动根据Content-Type指明的请求数据类型(如JSON、表单等)将请求数据进行parse解析,解析为类字典[QueryDict]对象保存到**Request**对象中。 **Request对象的数据是自动根据前端发送数据的格式进行解析之后的结果。** 无论前端发送的哪种格式的数据,我们都可以以统一的方式读取数据。
#### 1.1.1.1 常用属性
##### 1).data
`request.data` 返回解析之后的**请求体**数据。类似于Django中标准的`request.POST`和 `request.FILES`属性,但提供如下特性: - 包含了解析之后的文件和非文件数据 - 包含了对POST、PUT、PATCH请求方式解析后的数据 - 利用了REST framework的parser解析器,不仅支持表单类型数据,也支持JSON数据
##### 2).query_params
query_params,查询参数,也叫查询字符串(query string ) `request.query_params`与Django标准的`request.GET`相同,只是更换了更正确的名称而已。
##### 3)request._request
获取django封装的Request对象
#### 基本使用
视图代码:
from django.views import View from django.http.response import HttpResponse from django.http.request import HttpRequest from django.core.handlers.wsgi import WSGIRequest class ReqView(View): def get(self,request): print(request) return HttpResponse("ok") """ 默认情况下, 编写视图类时,如果继承的是django内置的django.view.View视图基类, 则视图方法中得到的request对象,是django默认提供的django.core.handlers.wsgi.WSGIRequest WSGIRequest这个请求处理对象,无法直接提供的关于json数据数据处理。 在编写api接口时很不方便,所以drf为了简写这块内容,在原来的HttpRequest的基础上面,新增了一个Request对象 这个Request对象是单独声明的和原来django的HttpRequest不是父子关系。 同时注意: 要使用drf提供的Request请求处理对象,必须在编写视图类时继承drf提供的视图基类 from rest_framework.views import APIView ********** 如果使用drf提供的视图基类APIView编写类视图,则必须使用来自drf提供的Request请求对象和Response响应对象 ********* """ from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status class ReqAPIView(APIView): def get(self,request): # rest_framework.request.Request对象 print(request) # <rest_framework.request.Request: GET '/req/req2?name=xiaoming&age=17&lve=swim&lve=code'> # 获取查询字符串 print(request.query_params) # 没有参数情况下: <QueryDict: {}> # 有参数的情况下: <QueryDict: {'name': ['xiaoming'], 'age': ['17'], 'lve': ['swim', 'code']}> # 所以,request.query_params的返回值操作和原来在django里面是一模一样的 print(request.query_params.get("name")) # xiaoming print(request.query_params.getlist("lve")) # ['swim', 'code'] return Response("ok") def post(self, request): # 获取请求体 print(request.data) # {'name': 'xiaoming', 'age': 16, 'lve': ['swim', 'code']} """直接从请求体中提取数据转 # 客户端如果上传了json数据,直接返回字典 {'name': '灰太狼', 'age': 20, 'sex': 1, 'classmate': '301', 'description': '我还会再回来的~'} # 客户端如果上传了表单数据,直接返回QueryDict <QueryDict: {'name': ['xiaohui'], 'age': ['18']}> """ print(request.FILES) # 获取上传文件列表 # 要获取django原生提供的HttpRequest对象,可以通过request._request来获取到 print(request._request.META.get("Accept")) # 当值为None时,drf默认在响应数据时按json格式返回 # response = Response(data="not ok", status=204, headers={"Company":"Oldboy"}) response = Response(data="not ok", status=status.HTTP_400_BAD_REQUEST, headers={"Company":"Oldboy"}) return response
### 1.1.2 Response
rest_framework.response.Response
REST framework提供了一个响应类`Response`,使用该类构造响应对象时,响应的具体数据内容会被转换(renderer渲染器)成符合前端需求的类型。
REST framework提供了`Renderer` 渲染器,用来根据请求头中的`Accept`(接收数据类型声明)来自动转换响应数据到对应格式。如果前端请求中未进行声明Accept,则会采用Content-Type方式处理响应数据,我们可以通过配置来修改默认响应格式。
可以在**rest_framework.settings**查找所有的drf默认配置项
```python
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': ( # 默认响应渲染类
'rest_framework.renderers.JSONRenderer', # json渲染器,返回json数据
'rest_framework.renderers.BrowsableAPIRenderer', # 浏览器API渲染器,返回调试界面
)
}