Django框架——视图

目录

    • Request
    • Response
    • APIView(一级视图)
    • GenericAPIView(二级视图)
    • Mixin
    • 子类视图(三级视图)
    • 路由Router


Request

REST framework 传入视图的request对象不再是Django默认的HttpRequest对象,而是REST framework提供的扩展了HttpRequest类的Request类的对象。
REST framework 提供了Parser解析器,在接收到请求后会自动根据Content-Type指明的请求数据类型(如JSON、表单等)将请求数据进行parse解析,解析为类字典对象保存到Request对象中。
Request对象的数据是自动根据前端发送数据的格式进行解析之后的结果。
无论前端发送的哪种格式的数据,我们都可以以统一的方式读取数据。

常用属性 描述
data request.data返回解析后的POST请求体数据。
query_params request.query_params返回解析后的GET请求体数据。

Response

REST framework提供了一个响应类Response,使用该类构造响应对象时,响应的具体数据内容会被转换(render渲染)成符合前端需求的类型。
REST framework提供了Renderer渲染器,用来根据请求头中的Accept(接收数据类型声明)来自动转换响应数据到对应格式。如果前端请求中未进行Accept声明,则会采用默认方式处理响应数据,我们可以通过配置来修改默认响应格式。
配置:

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (  # 默认响应渲染类
        'rest_framework.renderers.JSONRenderer',  # json渲染器
        'rest_framework.renderers.BrowsableAPIRenderer',  # 浏览API渲染器
    )
}

构造方式:

Response(data, status=None, template_name=None, headers=None, content_type=None)
参数 描述
data 为响应准备的序列化处理后的数据;
status 状态码,默认200;
template_name 模板名称,如果使用HTMLRenderer时需指明;
headers 用于存放响应头信息的字典;
content_type 响应数据的Content-Type,通常此参数无需传递,REST framework会根据前端所需类型数据来设置该参数。

APIView(一级视图)

继承自View父类,传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象;视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端要求的格式;
任何APIException异常都会被捕获到,并且处理成合适的响应信息;
在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。

支持定义的属性 描述
authentication_classes 列表或元组,身份认证类
permissoin_classes 列表或元组,权限检查类
throttle_classes 列表或元组,流量控制类

例:

from rest_framework.views import APIView
from rest_framework.response import Response

# url(r'^books/$', views.BookListView.as_view()),
class BookListView(APIView):
    def get(self, request):
        books = BookInfo.objects.all()
        serializer = BookInfoSerializer(books, many=True)
        return Response(serializer.data)

GenericAPIView(二级视图)

继承自APIVIew,增加了对于列表视图和详情视图可能用到的通用支持方法。通常使用时,可搭配一个或多个Mixin扩展类。
使用GenericAPIView类一般需要实现queryset属性或者重写get_queryset方法,需要实现serializer_class属性或重写get_serializer_class方法。
1.支持定义的属性:
列表视图与详情视图通用:

属性 描述
queryset 列表视图的查询集
serializer_class 视图使用的序列化器

列表视图使用:

属性 描述
pagination_class 分页控制类
filter_backends 过滤控制后端

详情页视图使用:

属性 描述
lookup_field 查询单一数据库对象时使用的条件字段,默认为’pk’
lookup_url_kwarg 查询单一数据时URL中的参数关键字名称,默认与look_field相同

2.提供的方法:
列表与详情通用:

get_queryset(self)
返回视图使用的查询集,是列表视图与详情视图获取数据的基础,默认返回queryset属性,可以重写,例如:
def get_queryset(self):
    user = self.request.user
    return user.accounts.all()

get_serializer_class(self)
返回序列化器类,默认返回serializer_class,可以重写,例如:
def get_serializer_class(self):
    if self.request.user.is_staff:
        return FullAccountSerializer
    return BasicAccountSerializer

get_serializer(self,_args, *_kwargs)
返回序列化器对象,被其他视图或扩展类使用,如果我们在视图中想要获取序列化器对象,可以直接调用此方法。
注意,在提供序列化器对象的时候,REST framework会向对象的context属性补充三个数据:request、format、view,这三个数据对象可以在定义序列化器时使用。

详情使用:

get_object(self)返回详情视图所需的模型类数据对象,默认使用lookup_field参数来过滤queryset。 在试图中可以调用该方法获取详情信息的模型类对象。
若详情访问的模型类对象不存在,会返回404。
该方法会默认使用APIView提供的check_object_permissions方法检查当前对象是否有权限被访问。

Mixin

配合GenericAPIView使用,将一些常用方法封装。
1.ListModelMixin:
快速实现列表视图,提供list(request, *args, **kwargs)方法,并返回200状态码。
例:

from rest_framework.mixins import ListModelMixin
from rest_framework.generics import GenericAPIView

class ListModelView(ListModelMixin,GenericAPIView):

    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

    def get(self,request):
        return self.list(request)

2.CreateModelMixin:
创建视图扩展类,提供create(request, *args, **kwargs)方法快速实现创建资源的视图, 成功返回201状态码。
如果序列化器对前端发送的数据验证失败,返回400错误。
例:

from rest_framework.mixins import CreateModelMixin

class ListModelView(CreateModelMixin,GenericAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

    def post(self,request):
        return self.create(request)

3.RetrieveModelMixin:
详情视图扩展类,提供retrieve(request, *args, **kwargs)方法,可以快速实现返回一个 存在的数据对象。
如果存在,返回200, 否则返回404。
例:

from rest_framework.mixins import RetrieveModelMixin

class ListModelView(RetrieveModelMixin,GenericAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

    def get(self,request,pk):

        return self.retrieve(request)

4.UpdateModelMixin:
更新视图扩展类,提供update(request, *args, **kwargs)方法,可以快速实现更新一个存 在的数据对象。
同时也提供partial_update(request, *args, **kwargs)方法,可以实现局部更新。
成功返回200,序列化器校验数据失败时,返回400错误。
例:

from rest_framework.mixins import UpdateModelMixin

class ListModelView(UpdateModelMixin,GenericAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

    def put(self,request,pk):
      return self.update(request)

5.DestoryModelMixin:
删除视图扩展类,提供destroy(request, *args, **kwargs)方法,可以快速实现删除一个存 在的数据对象。成功返回204,不存在返回404。
例:

from rest_framework.mixins import DestroyModelMixin

class ListModelView(DestroyModelMixin,GenericAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

    def delete(self,request,pk):
        return self.destroy(request)

子类视图(三级视图)

1.CreateAPIView
提供 post 方法
继承自: GenericAPIView、CreateModelMixin

2.ListAPIView
提供 get 方法
继承自:GenericAPIView、ListModelMixin

3.RetireveAPIView
提供 get 方法
继承自: GenericAPIView、RetrieveModelMixin

4.DestoryAPIView
提供 delete 方法
继承自:GenericAPIView、DestoryModelMixin

5.UpdateAPIView
提供 put 和 patch 方法
继承自:GenericAPIView、UpdateModelMixin

6.RetrieveUpdateAPIView
提供 get、put、patch方法
继承自: GenericAPIView、RetrieveModelMixin、UpdateModelMixin

7.RetrieveUpdateDestoryAPIView
提供 get、put、patch、delete方法
继承自:GenericAPIView、RetrieveModelMixin、UpdateModelMixin、DestoryModelMixin

例:
只需定义queryset和serializer_class,或重写get_queryset与get_serializer_class方法

from rest_framework.generics import CreateAPIView

class BookCreateAPIView(CreateAPIView):

    # queryset = BookInfo.objects.all()
    def get_queryset(self):

        return BookInfo.objects.all()

    # serializer_class = BookModelSerializer
    def get_serializer_class(self):
        return BookModelSerializer

路由Router

1.router对象:
SimpleRouter:不创建首页视图
DefaultRouter:创建首页视图
2.使用方法:
(1)创建router对象,并注册视图集:
用法:
register(prefix, viewset,base_name)

参数 描述
prefix 该视图集的路由前缀
viewset 视图集
base_name 路由名称的前缀

例:

from rest_framework import routers

router = routers.SimpleRouter()
router.register(r'books', BookViewSet, base_name='book')

如上述代码会形成的路由如下:
^books/$    name: book-list
^books/{pk}/$   name: book-detail

(2)添加路由数据:
可以有两种方式:

urlpatterns = [
    ...
]
urlpatterns += router.urls
或
urlpatterns = [
    ...
    url(r'^', include(router.urls))
]

3.视图集中包含附加动作:
使用action装饰器
用法:

@action(methods=[xxxx], detail)
参数 描述
methods 访问的方法
detail 是否为详情页面

例:

detail为True: ^books/{pk}/set_bookname/$    name: books-set-bookname
detail为False: ^books/order_comment/$       name: books-order-comment

你可能感兴趣的:(学习笔记)