请求与响应、视图
请求
#请求对象,把原来的request重新封装
from rest_framework.request import Request
def __init__(self, request, parsers=None, authenticators=None,
negotiator=None, parser_context=None):
# 二次封装request,将原生request作为drf request对象的 _request 属性
self._request = request
#.取值的时候从self._request(request)去获取对应的数据
def __getattr__(self,item):
return getattr(self._request,item)
#前端三种编码格式传入的数据,都可以从请求对象.data取
#请求对象.query_params与Django中的request.GET相同,只是换了个合适的名称
响应
#from rest_framework.response import Response
def __init__(self, data=None, status=None,
template_name=None, headers=None,
exception=False, content_type=None):
#data 你要返回的数据(是字典)
#status 返回的状态码,默认200(ok)
from rest_framework import status路径,把所有的状态码定义成了常量,这样使用status.常量名
return Response({'status':status.HTTP_208_ALREADY_REPORTED})
#headers 响应头,是字典可以放值,Response.headers['key']=values
#content_type 响应的编码格式,postman响应成application/json,浏览器是text/html
#template_name 渲染的模板名字(自定制模板),不需要了解
#drf默认的配置文件查找顺序
项目的settings.py>>>rest_framework.settings
#drf的配置信息,先从自己类>>>项目的setting.py>>>rest_framework.settings
视图
#两个视图基类
APIView
GenericAPIView
#基于APIView写接口
from rest_framework.views import APIView
from app01.models import Book
from app01.ser import BookSerializer
from rest_framework import status
class BookAPIView(APIView):
def get(self,request,*args,**kwargs):
#没有pk,查所有
if not kwargs.get('pk'):
book_list = Book.objects.all()
book_ser = BookSerializer(book_list,many=True)#many序列化多条
return Response(book_ser.data)
else:
#查单个
book = Book.objects.filter(pk=kwargs.get('pk')).first()
book_ser = BookSerializer(book)
return Response(book_ser.data)
#新增一个
def post(self,request):
book_ser = BookSerializer(data=request.data)
if book_ser.is_valid():
book_ser.save()#基于Serializer的需要在序列化类写create方法
return Response(book_ser.data)
else:
return Response({'status':101,'msg':'校检失败'})
def put(self,request,*args,**kwargs):
book = Book.objects.filter(pk=kwargs.get('pk')).first()
#修改需要传入修改的对象,修改的数据,序列化类写update方法
book_ser = BookSerializer(instance=book,data=request.data)
if book_ser.is_valid():
book_ser.save()
return Response(book_ser.data)
else:
return Response({'status':101,'msg':'校检失败'})
def delete(self,request,*args,**kwargs):
book = Book.objects.filter(pk=kwargs.get('pk')).delete()
return Response({'status':100,'msg':'删除成功'})
#序列化类是Serializer,需要在序列化类写create、update方法,ModelSerializer不用
def create(self, validated_data):
book_obj = Book.objects.create(**validated_data)
return book_obj
def update(self, instance, validated_data):
instance.name = validated_data.get('name')
instance.price = validated_data.get('price')
instance.author = validated_data.get('author')
instance.save()
return instance
#路由配置
#BookAPIView
re_path('bookapiview/(?P<pk>\d+)',views.BookAPIView.as_view()),
path('bookapiview/',views.BookAPIView.as_view()),
#基于GenericAPIView写接口
from rest_framework.generics import GenericAPIView
class BookGenericAPIView(GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
def get(self,*args,**kwargs):
if kwargs.get('pk'):
book = Book.objects.filter(pk=kwargs.get('pk')).first()
book_ser = self.get_serializer(book)
return Response(book_ser.data)
else:
book_list = self.get_queryset()
book_ser = self.get_serializer(book_list,many=True)
return Response(book_ser.data)
def post(self,request):
book_ser = self.get_serializer(data=request.data)
if book_ser.is_valid():
book_ser.save()
return Response(book_ser.data)
else:
return Response({'status':101,'msg':'校检失败'})
def put(self,request,*args,**kwargs):
book = Book.objects.filter(pk=kwargs.get('pk')).first()
book_ser = self.get_serializer(instance=book, data=request.data)
if book_ser.is_valid():
book_ser.save()
return Response(book_ser.data)
else:
return Response({'status':101,'msg':'校检失败'})
def delete(self,*args,**kwargs):
Book.objects.filter(pk=kwargs.get('pk')).delete()
return Response({'status':100,'msg':'删除成功'})
#路由配置
# BookGenericAPIView
re_path('bookgeneric/(?P<pk>\d+)', views.BookGenericAPIView.as_view()),
path('bookgeneric/', views.BookGenericAPIView.as_view()),
#基于GenericAPIView和5个视图扩展类写接口
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin
class BookGenerricmixin(GenericAPIView,ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
def get(self,request,*args,**kwargs):
pk = kwargs.get('pk')
if pk:
return self.retrieve(request,pk)
else:
return self.list(request)
def post(self,request):
return self.create(request)
def put(self,request,*args,**kwargs):
pk = kwargs.get('pk')
if pk:
return self.update(request,pk)
else:
return Response({'status':101,'msg':'没有pk值'})
def delete(self,request,*args,**kwargs):
pk=kwargs.get('pk')
if pk:
return self.destroy(request,pk)
else:
return Response({'status':101,'msg':'没有pk值'})
#路由配置
# Bookgenerricmixin
path('bookgenerricmixin/', views.BookGenerricmixin.as_view()),
re_path('bookgenerricmixin/(?P<pk>\d+)', views.BookGenerricmixin.as_view()),
使用ModelViewSet编写的5个接口手写路由
#每个请求方式对应的方法
path('books5/', views.BookModelViewSet.as_view(actions={'get':'list','post':'create'}))
re_path('books5/(?P<pk>\d+)', views.BookModelViewSet.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'}))
源码分析ViewMixin
# 重写了as_view
# 核心代码(所以路由中只要配置了对应关系,比如{'get':'list'}),当get请求来,就会执行list方法
for method, action in actions.items():
#method:get
# action:list
handler = getattr(self, action)
#执行完上一句,handler就变成了list的内存地址
setattr(self, method, handler)
#执行完上一句 对象.get=list
#for循环执行完毕 对象.get:对着list 对象.post:对着create
继承ViewSetMixin的视图类
# views.py
from rest_framework.viewsets import ViewSetMixin
class Book6View(ViewSetMixin,APIView): #一定要放在APIVIew前
def get_all_book(self,request):
print("xxxx")
book_list = Book.objects.all()
book_ser = BookSerializer(book_list, many=True)
return Response(book_ser.data)
# urls.py
#继承ViewSetMixin的视图类,路由可以改写成这样
path('books6/', views.Book6View.as_view(actions={'get': 'get_all_book'})),
查看继承关系