drf之控制编码格式、GenericAPIView、5个视图拓展类

1 drf之请求

1.1请求源码分析

导入:from rest_framework.request import Request

  1. 以后视图类的方法中的request都是这个类的对象
  2. 以后使用request.data 取请求体中的数据
  3. 以后使用request.query_params取请参数中的数据
  4. 以后其他属性,用起来跟之前一样—》重要
    request.method 的时候—》实际上 request._request.'method'—》反射出来的
    这个类from rest_framework.request import Request没有method,他会触发这个类的__getattr__
  5. FILES 用起来跟之前一样,前端传入的文件在里面

1.2 drf 之请求Request类

data
query_params
用起来跟之前一样

了解:

request._request
视图类的方法中: self 是咱们写的视图类的对象,self.request 是新的request

1.3 控制前端请求的编码格式

前端传入的编码:urlencoded ,josn ,form-data

如何某些接口只能接收某种编码的处理方式?

方法一:

局部使用,在视图类上配置

# 导入
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
# JSONParser:json格式
# FormParser:urlencoded格式
# MultiPartParser:form—data格式

class BookView(GenericAPIView,CreateModelMixin,ListModelMixin):
	# 允许哪个就在列表里添加哪个
    parser_classes = [JSONParser, FormParser]
方法二:

全局都生效,所有接口都支持某一种或某几种
settings.py文件中添加

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
        # 'rest_framework.parsers.MultiPartParser'
    ]
}
补充

全局使用后,局部再限制,只需要在视图类上加即可

class BookView(APIView):  # 全局如果用了,局部这样配,优先用局部的,也就是这个类管理的接口,只能接收form-data格式
    parser_classes = [MultiPartParser]

为什么我们没有配置,三种也支持?

drf自己有默认配置—》默认配置就是支持三种


2 drf之响应

2.1 drf之Response对象源码

导入:from rest_framework.response import Response
返回Response的时候有几个默认参数

def get(self, request):
    return Response(data={},status=500,headers={'xxx':'yyy'})
  1. data=None
    字符串,列表,字典,放在了响应体中,第一个参数是它
  2. status=None
    http响应状态码,默认是200,千万不能写成1xx
  3. headers=None
    http响应头,后期我们可以往响应头中放数据
  4. content_type=None
    响应编码格式(不用管,用浏览器访问就是:text/html,用postman就是:json格式)
  5. template_name=None
    模版名字 默认是:rest_framework/api.html 了解,可以定制自己返回的页面样子
补充
# 后面会用---》通过res.data 就能取到当时放的data
res=Response(data={},status=500,headers={'xxx':'yyy'})
print(res.data)
return res

### 取当时放的响应头
res.headers 拿不到数据,可以通过下面的方式或得到
print(res['xxx'])
print(res.has_header('zzz'))

2.2 drf之响应格式

响应有编码格式:默认支持json和text/html(浏览器)
postman只支持json格式,浏览器优先text/html

局部使用
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
# JSONRenderer:json格式
# BrowsableAPIRenderer:模版网页格式
class BookView(APIView):
   	renderer_classes = [BrowsableAPIRenderer]
全局使用
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],
}
局部禁用

全局已经配置了—》局部想用浏览器的样子
settings.py文件中添加

class BookView(APIView):
   	renderer_classes = [BrowsableAPIRenderer]
补充

如果不配置,有默认

  1. 解析:三种编码都能解析
  2. 响应:浏览器访问看到浏览器的样子,postman访问,看到json格式

3 两个视图基类

  1. Book 的 5个接口 基于APIView编写
  2. Publish 的5个接口 基于GenericAPIView编写

3.1 基于GenericAPIView(只要跟数据库打交道)

# 基于GenericAPIView

# 自己写GenericAPIView
from rest_framework.views import APIView
class GenericAPIView(APIView):
    queryset = None
    serializer_class = None

    def get_serializer(self, *args, **kwargs):
        return self.serializer_class(*args, **kwargs)

	# 方便拓展,方便重写拿到不一样的数据
    def get_queryset(self):
        return self.queryset.all()
        # 真正使用的时候,再加all获取所有才行

    def get_object(self, pk):
        res = self.queryset()
        return res.filter(pk=pk).first()


from .models import Book
from .serializer import BookSerializer


class BookView(GenericAPIView):
    # 类只要加载,就会执行,查了所有数据,不能以它为准
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request):
        # 以用的时候为准
        obj_list = self.get_queryset()
        ser = self.get_serializer(instance=obj_list, many=True)
        return Response(ser.data)

    def post(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valiad():
            ser.save()
            return Response(ser.data)
        else:
            return Response(ser.errors)


class BookDetailView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request, pk):
        obj = self.get_object(pk)
        ser = self.get_serializer(instance=obj)
        return Response(ser.data)

    def put(self, request, pk):
        obj = self.get_object(pk)
        ser = self.get_serializer(data=request.data, instance=obj)
        if ser.is_valiad():
            ser.save()
            return Response(ser.data)
        else:
            return Response(ser.errors)

    def delete(self, request, pk):
        self.get_object(pk).detele()
        return Response("")

3.2 GenericAPIView 有类属性和方法

重要属性
  1. queryset:以后放所有某个表查询出的数据
  2. serializer_class:要序列化的类
重要方法
  1. get_queryset :要序列化的所有数据,qs对象
  2. get_serializer :序列化类
  3. get_object :查询的单条
了解类属性
  1. lookup_field = 'pk':路由使用转换器,转换出来的参数,查询单条要用到,如果改了,路由对应也要修改,一般不改
  2. filter_backends:后面详细讲 过滤 功能
  3. pagination_class :后面详细讲 分页
了解方法
  1. get_serializer_class 后期咱们可能会重写它,指定某些方法使用不同的序列化类
  2. filter_queryset 后面跟过滤功能一起讲

4 5个视图扩展类(不是视图类,先继承GenericAPIView)

drf自己提供了5个视图拓展类,我们只要在视图类中继承使用就行

4.1 继承

  1. RetrieveModelMixin
    查询一条,写了一个方法retrieve,代码就是 跟咱们之前写获取单条get方法内容一样
  2. CreateModelMixin
    新增一条写了一个方法create,代码就是 跟咱们之前写新增一条 post 方法内容一样
  3. DestroyModelMixin
    删除一条写了一个方法destroy,代码就是 跟咱们之前写删除一条 delete 方法内容一样
  4. ListModelMixin
    查询所有写了一个方法list,代码就是 跟咱们之前写查询所有 get 方法内容一样
  5. UpdateModelMixin
    修改一个写了一个方法update,代码就是 跟咱们之前写修改一条put 方法内容一样

为什么写5个,不写俩?

因为后期不一定 5个接口都写

4.2 代码

## 基于基于 5个视图扩展类(不是视图类--》先继承GenericAPIView)

from rest_framework.generics import GenericAPIView
from rest_framework.mixins import RetrieveModelMixin, CreateModelMixin,DestroyModelMixin,ListModelMixin,UpdateModelMixin
from .models import Book
from .serializer import BookSerializer
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser

class BookView(GenericAPIView,CreateModelMixin,ListModelMixin):
    parser_classes = [JSONParser, FormParser]
    queryset = Book.objects.all()
    serializer_class = BookSerializer

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

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

class BookDetailView(GenericAPIView,RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request, pk):
        return self.retrieve(request, pk)

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值