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

 

posted on 2019-03-27 18:34  Afrafre  阅读(180)  评论(0编辑  收藏  举报