drf请求与响应、视图组件介绍

140 阅读3分钟

1.模型类序列化器(ModelSerializer)的使用

ModelSerializer与常规的Serializer相同,但提供了:

  • 基于模型类自动生成一系列字段(同样支持自定义字段)
  • 基于模型类自动为Serializer生成validators,比如unique_together
  • 包含默认的create()和update()的实现
serializer.py

from rest_framework import serializers
from app01 import models
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book  # modes指明参照哪个模型类
        fields = '__all__'  # fields指明为模型类的哪些字段生成  __all__表示所有字段
        # fields也可以写成 fields = ['id', 'name', 'price']
        extra_kwargs = {  # 使用extra_kwargs参数为ModelSerializer添加或修改原有的选项参数
            'name': {'min_length': 8, 'required': True},
            'price': {'min_value': 3, 'required': True},
        }
views.py

from rest_framework.response import Response
from rest_framework.views import APIView
from app01.models import Book
from app01.serializer import BookSerializer

class BookView(APIView):
    def get(self, request):
        book_list = Book.objects.all()
        ser = BookSerializer(instance=book_list, many=True)
        return Response(ser.data)
    def post(self, request):
        ser = BookSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '新增成功'})
        else:
            return Response({'code': 101, 'msg': ser.errors})

class BookDetailView(APIView):
    def get(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=book)
        return Response(ser.data)
    def put(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=book, data=request.data)
        if ser.is_valid():
            return Response({'code': 100, 'msg': '修改成功'})
        else:
            return Response({'code': 101, 'msg': ser.errors})
    def delete(self, request, pk):
        Book.objects.filter(pk=pk).delete()
        return Response('')

2.请求与响应

2.1Request类与Response类

# 继承APIView后 请求对象request--》每一次请求都是新的request

# Request类
	Request.data:  不仅能取到原生django的.POST和.body中的数据。也能取到django取不到的put、petch请求提交的数据
	Request.query_params:  与Django标准的request.GET相同,只是更换了更正确的名称而已。
# Response类
	构造方式:Response(data, status=None, template_name=None, headers=None, content_type=None)
	-data:经过序列化处理过后的数据(json格式字符串,放在http响应body体中返回给前端)
	-status:状态码,默认200
	-template_name:模板名称,如果使用HTMLRender时须指明
	-header:用于存放响应头信息的字典  {'name': 'jason'}
	-content-type:响应数据的格式  (一般是json) 

2.2drf能够解析的请求编码

drf默认能够解析 -urlencoded  -form-data  -json 这三种格式的数据

# 其实可以通过配置修改
drf有两套配置 一套是项目中的配置(settings.py),一套是drf自己默认的配置
-drf的配置文件settings.py中有 DEFAULT_PARSER_CLASSES(默认的解析类)
    -'rest_framework.parsers.JSONParser', 可以解析json格式
    -'rest_framework.parsers.FormParser', 可以解析urlencoded格式
    -'rest_framework.parsers.MultiPartParser' 可以解析form-data格式

如果想让我们的接口只接受json格式
方式1:全局配置(setting.py)
	REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES': [
            'rest_framework.parsers.JSONParser',
            # 'rest_framework.parsers.FormParser',
            # 'rest_framework.parsers.MultiPartParser',
        ],
	}
方式2:局部配置(view.py)
class TestView(APIView):
	parser_classes = [JSONParser,FormParser,MultiPartParser]
	...

# 总结:
	解析类的顺序:优先使用视图类自己的--》项目配置文件--》drf内置的
	实际项目如何配置:
    	-基本上都允许JSONParser,FormParser
        -如果上传文件只允许MultiPartParser

2.3:drf能解析的响应编码

如果用浏览器访问能看到页面  Content-Type: text/html;
如果用postman访问只能看到数据  Content-Type: json;

# 全局配置:在项目的配置文件
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
    	# 'rest_framework.renderers.JSONRenderer', # json格式
    	'rest_framework.renderers.BrowsableAPIRenderer', #浏览器的格式
    ]
}

# 局部配置:
class TestView(APIView):
    renderer_classes = [JSONRenderer,]

3.drf之视图组件

# APIView

# GenericAPIView-->继承了APIView
	-类属性:
    	queryset = User.objects.all()
    	serializer_class = UserSerializer
    -方法:
    	 self.get_object() # 根据pk获取单个数据
         self.get_serializer # 获取要使用的序列化类
         self.get_queryset() # 获取所有要序列化数据

4. 作业

# 9个视图子类
class GetAll(GenericAPIView):
    def get(self, request):
        book_list = self.get_queryset()
        ser = self.get_serializer(instance=book_list, many=True)
        return Response(ser.data)


class Create(GenericAPIView):
    def post(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': "新增成功"}, status=201)
        else:
            return Response({'code': 101, 'msg': ser.errors})


class GetOne(GenericAPIView):
    def get(self, request, pk):
        book = self.get_object()
        ser = self.get_serializer(instance=book)
        return Response(ser.data)


class Update(GenericAPIView):
    def put(self, request, pk):
        book = self.get_object()
        ser = self.get_serializer(instance=book, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': "修改成功"}, status=201)
        else:
            return Response({'code': 101, 'msg': ser.errors})


class Delete(GenericAPIView):
    def delete(self, request, pk):
        self.get_queryset().filter(pk=pk).delete()
        return Response('')


class GetAllAndCreate(GetAll, Create):  # 查询所有、新增一个
    pass


class GetOneAndDeleteAndUpdate(GetOne, Delete, Update):
    pass


class GetOneAndDelete(GetOne, Delete):
    pass


class GetOneAndUpdate(GetOne, Update):
    pass


# 视图类
class BookView(GetAllAndCreate):
    queryset = Book.objects.all()
    serializer_class = BookSerializer


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