1. 继承ModelSerilizer,直接指定要序列化的表模型 MySerializers.py
from app import models # 继承ModelSerilizer,直接指定要序列化的表模型 class BookSerializer(serializers.ModelSerializer): class Meta: # 内部类 # 指定要序列化book表 model = models.Book # 序列化所有的字段 fields = '__all__' #---------------------------------------------------------------- #局部钩子校验, 只要是Book 的字段均可以进行局部校验 def validate_name(self,value): # value 就是name字段的值 if value.startswith('sb'): raise ValidationError('书名不能以sb开头!') else: return value #全局钩子校验 def validate(self,attrs): # 所有的都传过来 # OrderedDict([('name', 'php'), ('price', Decimal('33.00')), ('publish_date', datetime.date(2019, 3, 18)), # ('publish', < Publish: 北京出版社 >), ('author', [ < Author: liu >])]) print(attrs) #是一个字典, 是所有属性的键值对 return attrs
第一层封装:
class BooksView(APIView): ''' book_ser 的data 属性就是 字典 book_ser = BookSerializer(book_list,many=True) response['data']= book_ser.data # 这里就是将book_list 对象转化成为字典 book_ser.data book_ser = BookSerializer(data=request.data) # 这里是将request.data 字典转换为对象,对象可以存进数据库 book_ser.save() 返回给前台的data 仍然是字典 即,book_ser 的data book_ser.errors 专门用来放错误信息 ''' def get(self,request,*args,**kwargs): book_list = Book.objects.all() # queryset对象,序列化称为列表 response = {'status':100,'msg':'查询成功'} # 使用BookSerializer, 将对象转化成为字典 book_ser = BookSerializer(book_list,many=True) print(book_ser) print(book_ser.data) response['data']= book_ser.data return Response(response) def post(self,request): # 新增图书 # 将data取出,反序列化成对象,然后将对象存入数据库,然后前台返回字典信息 book_ser.data # 注意添加book 的时候一定选择JSON response = {'status':100,'msg':'插入成功'} print(request.data) try: # 将字典反序列化为对象 book_ser = BookSerializer(data=request.data) if book_ser.is_valid(): book_ser.save() response['data'] = book_ser.data else: response['msg'] = book_ser.errors except Exception as e: response['msg']=str(e) return Response(response) class SingleBook(APIView): # 获得单本图书, get,post 都要request参数 def get(self,request,id,*args, **kwargs): response = { 'status':100, 'msg':'查询成功' } book = Book.objects.filter(pk=id).first() book_ser = BookSerializer(instance=book,many=False) response['data']=book_ser.data return Response(response) def put(self,request,id): # 修改图书,存入数据库的都是对象,所以要反序列化字典为对象 response = { 'status':100, 'msg': '修改成功!' } book = Book.objects.filter(pk=id).first() try: # 这里是修改,不是新增,因此要添加instance 这个字段, 注意这里不是query_set 对象 book_ser = BookSerializer(instance=book,data=request.data) if book_ser.is_valid(): book_ser.save() response['data']=book_ser.data else: response['data']=book_ser.errors except Exception as e: response['msg'] = str(e) return Response(response) def delete(self,request,id): # 删除返回的data 为空 response = { 'status':100, 'msg':'删除成功!', 'data':'' } book = Book.objects.filter(pk=id).delete() # queryset对象 return Response(response)
第二层封装:
# 以上是对书的增删改查方法, 对作者,出版社同样可以增删改查 # 所以可以将增删改查方法提出来,然后进行调用就可以了 # 继承,封装 # 增删改查,每个方法封装一个类, 继承就可以获得相应的 get, put等方法 # drf 提供的 封装好的类 from rest_framework.mixins import ListModelMixin,RetrieveModelMixin,CreateModelMixin,DestroyModelMixin,UpdateModelMixin from rest_framework.generics import GenericAPIView class BookView(ListModelMixin,CreateModelMixin,GenericAPIView): ''' LsitModeMixin 中: serializer = self.get_serializer(page, many=True) ----》 找不到get_serializer 方法 GenericAPIView : 有get_serializer 方法 返回 return serializer_class(*args, **kwargs), 就是book_ser = BookSerializer(book_list,many=True) 所以: serializer 就是 book_ser( 序列化后的JSON 数据) serializer_class = BookSerializer ''' serializer_class = BookSerializer queryset = Book.objects.all() # 获得多个 def get(self,request,*args,**kwargs): return self.list(request,*args,**kwargs) # 新添 def post(self,request,*args,**kwargs): return self.create(request,*args,**kwargs) class Single_book(RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView): ''' 进入 RetrieveModelMixin: instance = self.get_object() 进入 GenericAPIView : get_object() 方法 ----》 get_queryset() ---》 queryset = queryset.all() 所以: 需要提供 queryset , 即 queryset = Book.objects.all() ''' serializer_class = BookSerializer queryset = Book.objects.all() # 获取单条 def get(self,request,*args,**kwargs): return self.retrieve(request,*args,**kwargs) def put(self,request,*args,**kwargs): return self.update(request,*args,**kwargs) def delete(self,request,*args,**kwargs): return self.destroy(request,*args,**kwargs)
第三层封装:
# 还可以继续封装, 将类中的方法 封装成一个 # 第三层: 使用rest_framework.generics import ListAPIView,ListCreateAPIView from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView # 包含两个方法 get and post class BookView(ListCreateAPIView): serializer_class = BookSerializer queryset = Book.objects.all() # 包含三个方法, get,put,delete class Single_book(RetrieveUpdateDestroyAPIView): serializer_class = BookSerializer queryset = Book.objects.all()
第四层封装:
# 第四层,可以将五个方法封装到一个类中 # 为了区分两个get 方法, 路由中的as_view() 方法要重写 # url(r'^book/$', views.BooksView.as_view({'get':'list','post':'create'})), # url(r'^book/(?P<id>w+)/$', views.SingleBook.as_view({'get':'retrive','put':'update','delete':'destroy'})), from rest_framework.viewsets import ModelViewSet class BookView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer
ViewSetMixin 的使用,重新了as_view 方法
# 经常用ViewSetMixin 只是重写了as_view() 方法 # as_view 就是将字典中的键值对应起来,所以值可以为任意自定义的函数 from rest_framework.viewsets import ViewSetMixin # 继承属性不能错!!! class Publish(ViewSetMixin,APIView): def aa(self,request): return HttpResponse('aa') # url(r'^book/$', views.BooksView.as_view({'get': 'aa'}) def get_all(self,request): # 就相当于之前定义的list 方法 pass #在路由中与之对应即可 def create(self,request): pass