drf day 04
今日内容详细
一、drf之请求与响应
1.1 Request类和Response类
1. 继承APIView后,请求对象:request------> 每一次的请求都是一个新的request。
通过http请求,给了django,django看不懂http请求,所以把他包装成了request,所以你才能点body,点get,点什么什么,搞到对象里面了,我们drf又给他重新包装,
但是原来的request也在里面,所以每一次请求都是新的request;我们每次请求都是三次握手,然后返回一坨东西,我们把这一坨东西称为response,一出django就变成了http响应,
来到了前端,展示给客户看,然后这个http就结束了。
2. Request类的属性或方法(drf的请求)
① data:POST、PUT、PATCH请求方式解析的数据
-原生django,put提交的数据在request.POST是取不到的
② query_params
③ 其他的用起来跟之前一样用(FILES,,method,path...)----> __getattr__
3. Response类(drf的响应)
Response(字典,列表)
Response的属性:
(1)data = None, 字典和列表都给了data---->data会序列化成json格式字符串,返回给前端(其实是放在http响应的body中了)
(2)status = None, 针对http响应的状态码,默认是200,如果新增的话改成201更好
(3)headers=None, http的响应头,它是一个字典{name:lqz}
-如何向响应头里面增加数据?
class TextView(APIView);
def get(slef,request):
d = {'name':'wyn','age':18}
# 原生django如何向响应头里面添加数据,四件套都可以
res = HttpResponse(json.dumps(d))
res = JsonRsponse(d)
res['rrr'] = yyy
return res
# 新的Response向响应头里面添加数据非常简单,直接使用headers参数
return Response(d,status=HTTP_201_CREATE,headers={'name':'wyn'})
(4) template_name=None 了解即可,就是在浏览器中看到的好看的页面,是指定的模板
(5)content_type=None 响应的编码格式(默认是json格式,但是这句话又不完全准确,具体看是向浏览器发送请求,还是向postman发送的请求)【你以为请求有编码,响应就没有编码了吗】
1.2 drf能够解析的请求编码,响应编码
一. 能够解析的请求编码
1. 默认能解析:
-urlencoded
-form-data
-json
2. 其实通过配置完成:在项目中是没有配置的,但是在drf内置的配置文件中提前配好了(项目中配置文件,内置中也有配置文件)
①-drf也是有两套配置,一套是项目中的配置(settings.py),一套是默认的配置
②-drf的配置文件( restframework/settings.py )中有DEFAULE_PARSER_CLASSES(是默认的解析类)
-'rest_framework.parsers.JSONParser',可以解析json格式
-'rest_framework.parsers.FORMParsers',可以解析urlencoded格式
-'rest_framework.parsers.MultiParsers',可以解析form-data格式
③-想让我们的接口只能接收json格式
方式一:全局配置--->就是在项目中配置文件--->那么以后的所有的接口都遵循这个项目中的配置
但是这种方法不好,无法上传文件了
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
# 'rest_framework.parsers.FormParser',
# 'rest_framework.parsers.MultiPartParser',# 这两句都注释掉了,那么drf只能解析JSON格式了,成功完成我们想要的需求
],
}
方式二:局部配置--->在views.py中配置
from rest_framework.parsers import JSONParser,FormParser,MultiPartParser
Class TestView(APIView):
parser_classes = [JSONParser,FormParser,MultiPartser] # 这种是三种格式都可以编码
parser_classes = [JSONParser] # 只能编码Json格式
-总结:
解析类的使用顺序:优先用视图自己的,然后用项目配置文件的,最后用内置的(可以理解为从近到远)
-实际项目如何配置
-基本上都运行JSONParser,FormParser
-如果上传文件只允许MultiParser
二、能够处理的响应编码
1. 如果使用浏览器,显示好看的样子,如果用postman看到json格式
-默认情况下显示的编码是根据客户端类型决定的
2. 全局配置:在项目的配置文件
RESR_FRAMEWORK = {
'DEFAULT_RENDERE_CLASSES':[
'rest_framework.renderers.JSONRenderer', # json格式
'rest_framework.renderers.BrowsableAPIRenderer' # 浏览器的格式(就是rest_framework好看的样子)
]
}
3. 局部配置:--->在views.py中配置
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
Class TestView(APIView):
renderer_classes = [JSONRenderer,]
-实际编码中,响应编码一般不去自己配,就用默认的
二、两个视图基类
2.1 基于APIView写5个接口
lass UserView(APIView):
def get(self, request):
book_list = User.objects.all()
ser = UserSerializer(instance=book_list, many=True)
return Response(ser.data)
def post(self, request):
ser = UserSerializer(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 UserDetailView(APIView):
def get(self, request, pk):
book = User.objects.filter(pk=pk).first()
ser = UserSerializer(instance=book)
return Response(ser.data)
def put(self, request, pk):
book = User.objects.filter(pk=pk).first()
ser = UserSerializer(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})
def delete(self, request, pk):
User.objects.filter(pk=pk).delete()
return Response('')
2.2 基于GenericAPIView写五个接口
from rest_framework.generics import GenericAPIView
class UserView(GenericAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
def get(self, request):
book_list = self.get_queryset()
ser = self.get_serializer(instance=book_list, many=True)
return Response(ser.data)
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 UserDetailView(GenericAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
def get(self, request, pk):
book = self.get_object()
ser = self.get_serializer(instance=book)
return Response(ser.data)
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})
def delete(self, request, pk):
self.get_queryset().filter(pk=pk).delete()
return Response('')
作业:
views.py
使用GenericAPIView写出book的5个接口
from rest_framework.generics import GenericAPIView
class BookView(GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request):
book_list = self.get_queryset()
ser = self.get_serializer(instance=book_list, many=True)
return Response(ser.data)
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 BookDetailView(GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request, pk):
book = self.get_object()
ser = self.get_serializer(instance=book)
return Response(ser.data)
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})
def delete(self,request,pk):
self.get_queryset().filter(pk=pk).delete()
return Response('')
serializer
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
使用面向对象,写5个父类, 继承GenericAPIView+某几个父类后,就有某几个接口
class AllBook(GenericAPIView):
def get(self,request):
book_list = Book.objects.all()
res = self.serializer_class(instance=book_list,many=True)
return Response(res.data)
class PostBook(GenericAPIView):
def post(self,request):
res = self.serializer_class(data=request.data)
if res.is_valid():
res.save()
return Response({'code':100,'msg':'新增成功'},status=201)
else:
return Response({'code':100,'msg':res.errors})
class OneBook(GenericAPIView):
def get(self,request,pk):
book = self.serializer_class(instance=book)
return Response(res.data)
class PutBook(GenericAPIView):
def put(self,request,pk)
book = self.get_object()
res = self.serializer_class(instance=book,data=request.data)
if res.is_valid():
res.save()
return Response({'code':100,'msg':'修改成功'})
esle:
return Response({'code':101,'msg':res.errors})
class DeleteBook(GenericAPIView):
def delete(self,request,pk):
self.get_queryset().filter(pk=pk).delete()
return Response('')
class BookView(AllBook,PostBook):
queryset = Book.objects.all()
serializer_class = BookSerializer
class BookDetailView(OneBook,PutBook,DeleteBook):
queryset = Book.objects.all()
serializer_class = BookSerializer

浙公网安备 33010602011771号