Django restframework之使用序列化组件增加与修改

Django restframework之使用序列化组件增加与修改

一 前言

在 views 视图中写 API 接口时,使用序列化组件来进行增删查改特别方便,本篇博客详细介绍一下在 views 中具体使用序列化组件。

二 V1版代码

一 v1版 views 代码

from rest_framework.response import Response
from rest_framework.views import APIView

from app01 import models
from app01.myser import BookSerib

# class Author(View):
#     pass


class Books(APIView):

    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    # @staticmethod
    def get(self, request, *args, **kwargs):

        response = {'status': 100, 'msg': None}

        book_list = models.Book.objects.all()
        book_ser = BookSerib(book_list, many=True)
        print('book_ser.data', book_ser.data)
        response['books'] = book_ser.data
        print('response', response)
        return Response(response)

    def post(self, request, *args, **kwargs):
        response = {'status': 100, 'msg': None}
        bookname = request.data.get('name')
        price = request.data.get('price')
        publish = request.data.get('publish')
        authors = request.data.get('author')
        # print(authors)

        if bookname and price and publish and authors:
            pub_obj = models.Publish.objects.filter(name=publish).first()
            book = models.Book.objects.filter(name=bookname).first()
            if book:
                response['msg'] = '图书已存在'

            else:

                if pub_obj:
                    authstr_list = [author.strip() for author in authors.split(',')]
                    # print('authstr_list', authstr_list)
                    auth_list = []
                    for author in authstr_list:
                        auth_obj = models.Author.objects.filter(name=author).first()
                        if auth_obj:
                            auth_list.append(auth_obj)
                    if auth_list:
                        # print('request.data', request.data)
                        ins_dic = dict(request.data)
                        # print(type(ins_dic))
                        ins_dic.pop('author')
                        # print('ins_dic', ins_dic)
                        book_obj = models.Book.objects.create(name=bookname, price=price, publish=pub_obj)

                        book_data = BookSerib(book_obj, many=False)

                        # print('book_obj', book_obj)
                        # ret = book_obj.author.add(*auth_list)
                        for auth in auth_list:
                            models.Book2Author.objects.create(book=book_obj, author=auth)
                        # print('ret', ret)
                        response['msg'] = '新增图书成功'
                        response['book'] = book_data.data
                    else:
                        response['msg'] = '作者不存在'
                else:
                    response['msg'] = '出版社不存在'
        else:
            response['msg'] = '信息不完整'

        return Response(response)

二 v1版 myser 代码

# myser.py

class AuthorSerib(serializers.Serializer):
    name_author = serializers.CharField(source='name')
    phone_num = serializers.CharField(source='phone')

class BookSerib(serializers.ModelSerializer):
    
    class Meta:
        fields = '__all__' # 序列化 Book 表中所有字段
        fields = ['name', 'price', 'publish'] # 选择性的序列化字段
        exclude = ['pub_date'] # 列表里面的字段不序列化
        depth = 1 # 连表查询的深度,不建议使用,因为深度查询的参数不能控制
        
    publish_name = serializers.CharField(source='publish.name') # 因为在 Book 表中外键关联了 publish 表,所以可以通过点语法取值
    authors = serializers.SerializerMethodField()
    
    def get_authors(self, obj): # 在那个类中调用该序列化类,比如需要获取 Book 信息,使用 BookSerib 类来序列化数据,那么 obj 就是 Book 类。
        author_list = obj.author.all()
        author_ser = AuthorSerib(author_list, many=True)
        return author_ser.data 

三 V2版代码

一 v2版 views 代码

class Book(APIView):

    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request, id):

        response = {'status': 100, 'msg': None}

        book = models.Book.objects.filter(pk=id).first()
        book_ser = BookSerib(book, many=False)
        print('book_ser.data', book_ser.data)
        response['books'] = book_ser.data
        response['msg'] = '获取图书成功'
        print('response', response)
        return Response(response)

    # 删除图书
    def delete(self, request, id):
        response = {'status': 100, 'msg': None}

        book = models.Book.objects.filter(pk=id).delete()
        # book_ser = BookSerib(book, many=False)
        response['msg'] = '删除成功'
        return Response(response)


    def post(self, request, *args, **kwargs):
        response = {'status': 100, 'msg': '成功'}
        # book_info = request.data
        book_ser = BookSerib(data=request.data)
        # 新方法,使用序列化组件保存,但是必须是继承自 ModelSerializer 的序列化类,这样才可以知道要保存的表模型
        if book_ser.is_valid():
            book_ser.save()
            response['book'] = book_ser.data
        else:
            response['msg'] = book_ser.errors
        return Response(response)

    def put(self, request, id):
        response = {'status': 100, 'msg': '成功'}
        book_obj = models.Book.objects.filter(pk=id).first()
        # 修改的话,要把 book 对象当做 instance传进去
        book_ser = BookSerib(data=request.data, instance=book_obj)
        # 新方法,使用序列化组件保存,但是必须是继承自 ModelSerializer 的序列化类,这样才可以知道要保存的表模型
        if book_ser.is_valid():
            # save既可以修改也可以新增
            book_ser.save()
            response['book'] = book_ser.data
        else:
            response['msg'] = book_ser.errors
        return Response(response)
posted @ 2019-02-22 10:39  rsuxwvilc  阅读(495)  评论(0)    收藏  举报