复习
"""
1、整体修改与局部修改
# 序列化
ser_obj = ModelSerializer(model_obj)
# 反序列化,save() => create()
ser_obj = ModelSerializer(data=model_data)
# save() => update()
ser_obj = ModelSerializer(instance=model_obj,data=model_data)
# partial=True => 匹配字段required=True校验条件
ser_obj = ModelSerializer(instance=model_obj,data=model_data,partial=True)
2、群改ListSerializer
ser_obj = ModelSerializer(instance=model_obj,data=model_data,partial=True,many=True)
# 一旦设置了many=True,反序列化情况下的create、update就不再调用ModelSerializer的
# 而是调用 ModelSerializer.Meta.list_serializer_class 指向的 ListSerializer 类的create、update
# ListSerializer默认只实现了群增的create,要实现群改,必须重写update
class MyListSerializer(ListSerializer):
def update(self, instance, validated_data):
# print(instance) # 要更新的对象们: [obj1, obj2, ...]
# print(validated_data) # 更新的对象对应的数据们: [{}, {}, ...]
# print(self.child) # 服务的模型序列化类 - V2BookModelSerializer
for index, obj in enumerate(instance):
self.child.update(obj, validated_data[index])
return instance
class MyModelSerializer(ModelSerializer):
class Meta:
# ...
list_serializer_class = MyListSerializer
将两者类建立关联,在MyListSerializer中就可以用self.child拿到MyModelSerializer,进而使用MyModelSerializer中封装好的方法
cls.Meta.list_serializer_class.child = cls
"""
视图类传递参数给序列化类
视图层:views.py
class Book ( APIView) :
def post ( self, request, * args, ** kwargs) :
book_ser = serializers. BookModelSerializer( data= request_data, context= { 'request' : request} )
book_ser. is_valid( raise_exception= True )
book_result = book_ser. save( )
return Response( {
'status' : 0 ,
'msg' : 'ok' ,
'results' : serializers. BookModelSerializer( book_result) . data
} )
序列化层:serializers.py
class BookModelSerializer ( ModelSerializer) :
class Meta :
model = models. Book
fields = ( 'name' , 'price' )
def validate_name ( self, value) :
print ( self. context. get( 'request' ) . method)
return value
二次封装Response类
"""
Response({
'status': 0,
'msg': 'ok',
'results': [],
'token': '' # 有这样的额外的key-value数据结果
},status=http_status,headers=headers,exception=True|False)
APIResponse() => Response({'status': 0,'msg': 'ok'})
"""
from rest_framework. response import Response
class APIResponse ( Response) :
def __init__ ( self, data_status= 0 , data_msg= 'ok' , results= None , http_status= None , headers= None , exception= False , ** kwargs) :
data = {
'status' : data_status,
'msg' : data_msg,
}
if results is not None :
data[ 'results' ] = results
data. update( kwargs)
super ( ) . __init__( data= data, status= http_status, headers= headers, exception= exception)
视图家族
"""
views:视图
generics:工具视图
mixins:视图工具集
viewsets:视图集
"""
"""
学习曲线
APIView => GenericAPIView => mixins的五大工具类 => generics中的工具视图 => viewsets中的视图集
"""
GenericAPIView基类
urlpatterns = [
url( r'^v2/books/$' , views. BookGenericAPIView. as_view( ) ) ,
url( r'^v2/books/(?P<pk>.*)/$' , views. BookGenericAPIView. as_view( ) ) ,
]
from rest_framework. generics import GenericAPIView
class BookGenericAPIView ( GenericAPIView) :
queryset = models. Book. objects. filter ( is_delete= False )
serializer_class = serializers. BookModelSerializer
lookup_field = 'pk'
def get ( self, request, * args, ** kwargs) :
book_query = self. get_object( )
book_ser = self. get_serializer( book_query)
book_data = book_ser. data
return APIResponse( results= book_data)
mixins视图工具集 - 辅助GenericAPIView
urlpatterns = [
url( r'^v3/books/$' , views. BookMixinGenericAPIView. as_view( ) ) ,
url( r'^v3/books/(?P<pk>.*)/$' , views. BookMixinGenericAPIView. as_view( ) ) ,
]
from rest_framework. mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin
class BookMixinGenericAPIView ( ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, GenericAPIView) :
queryset = models. Book. objects. filter ( is_delete= False )
serializer_class = serializers. BookModelSerializer
def get ( self, request, * args, ** kwargs) :
if 'pk' in kwargs:
response = self. retrieve( request, * args, ** kwargs)
else :
response = self. list ( request, * args, ** kwargs)
return APIResponse( results= response. data)
def post ( self, request, * args, ** kwargs) :
response = self. create( request, * args, ** kwargs)
return APIResponse( results= response. data)
def put ( self, request, * args, ** kwargs) :
response = self. update( request, * args, ** kwargs)
return APIResponse( results= response. data)
def patch ( self, request, * args, ** kwargs) :
response = self. partial_update( request, * args, ** kwargs)
return APIResponse( results= response. data)
工具视图
urlpatterns = [
url( r'^v4/books/$' , views. BookListCreatePIView. as_view( ) ) ,
url( r'^v4/books/(?P<pk>.*)/$' , views. BookListCreatePIView. as_view( ) ) ,
]
from rest_framework. generics import ListCreateAPIView, UpdateAPIView
class BookListCreatePIView ( ListCreateAPIView, UpdateAPIView) :
queryset = models. Book. objects. filter ( is_delete= False )
serializer_class = serializers. BookModelSerializer
视图集
urlpatterns = [
url( r'^v5/books/$' , views. BookGenericViewSet. as_view( { 'get' : 'my_get_list' } ) ) ,
url( r'^v5/books/(?P<pk>.*)/$' , views. BookGenericViewSet. as_view( { 'get' : 'my_get_obj' } ) ) ,
]
from rest_framework. viewsets import GenericViewSet
from rest_framework import mixins
class BookGenericViewSet ( mixins. RetrieveModelMixin, mixins. ListModelMixin, GenericViewSet) :
queryset = models. Book. objects. filter ( is_delete= False )
serializer_class = serializers. BookModelSerializer
def my_get_list ( self, request, * args, ** kwargs) :
return self. list ( request, * args, ** kwargs)
def my_get_obj ( self, request, * args, ** kwargs) :
return self. retrieve( request, * args, ** kwargs)
GenericAPIView 与 APIView 最为两大继承视图的区别
工具视图集
urlpatterns = [
url( r'^v6/books/$' , views. BookModelViewSet. as_view( { 'get' : 'list' , 'post' : 'create' } ) ) ,
url( r'^v6/books/(?P<pk>.*)/$' , views. BookModelViewSet. as_view( { 'get' : 'retrieve' , 'put' : 'update' , 'patch' : 'partial_update' , 'delete' : 'destroy' } ) ) ,
]
from rest_framework. viewsets import ModelViewSet
class BookModelViewSet ( ModelViewSet) :
queryset = models. Book. objects. filter ( is_delete= False )
serializer_class = serializers. BookModelSerializer
def destroy ( self, request, * args, ** kwargs) :
instance = self. get_object( )
if not instance:
return APIResponse( 1 , '删除失败' )
instance. is_delete = True
instance. save( )
return APIResponse( 0 , '删除成功' )
路由组件(了解)
from django. conf. urls import include
from rest_framework. routers import SimpleRouter
router = SimpleRouter( )
router. register( 'v6/books' , views. BookModelViewSet)
urlpatterns = [
url( r'^' , include( router. urls) ) ,
]