首页 > 其他分享 >drf之视图

drf之视图

时间:2023-01-31 23:36:46浏览次数:58  
标签:request 视图 django framework import drf

# 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渲染器,返回调试界面
)
}

#### 1.1.2.1 构造方式

标签:request,视图,django,framework,import,drf
From: https://www.cnblogs.com/TodayWind/p/17081160.html

相关文章