Django学习之DRF02

Serializer序列化器之反序列化操作
    1.调⽤序列化器进⾏验证
        0.准备序列化器

class BookInfoSerializer(serializers.Serializer):
 """图书数据序列化器"""
               id = serializers.IntegerField(label= 'ID', read_only= True)
               btitle = serializers.CharField(label= )
               bpub_date = serializers.DateField(label= ' 发布⽇期' , required= False)
               bread = serializers.IntegerField(label= ' 阅读量' , required= False)
               bcomment = serializers.IntegerField(label= ' 评论量' , required= False)
               image = serializers.ImageField(label= ' 图⽚' , required= False)
               heroinfo_set = serializers.PrimaryKeyRelatedField(read_only= True, many= True)

1.验证失败的情况
            >>> from booktest.serializers import BookInfoSerializer
            >>> data = {}
            >>> s = BookInfoSerializer(data=data)
            >>> s.is_valid()
            False
            >>> s.errors
            {'btitle': [ErrorDetail(string='This field is required.', code='required')]}
        2.验证成功的情况
            >>> data = {'btitle':'⽔浒传'}
            >>> s = BookInfoSerializer(data=data)
            >>> s.is_valid()
            True
            >>> s.validated_data
            OrderedDict([('btitle', '⽔浒传')])
        3.验证同时抛异常
            >>> data = {}
            >>> s = BookInfoSerializer(data=data)
            >>> s.is_valid(raise_exception=True)
            Traceback (most recent call last):
            File "<console>", line 1, in <module>
            File "/Users/zhangjie/.virtualenvs/ py3_django/lib/python3.6/site-packages/rest_framework/serializers.py", line 244, in is_valid
            raise ValidationError(self.errors)
            rest_framework.exceptions.ValidationError: {'btitle': [ErrorDetail(string='This field is required.', code='required')]}
    2.定义序列化器进⾏验证
        1.单个字段验证
            1.准备序列化器

class BookInfoSerializer(serializers.Serializer):
"""图书数据序列化器"""
    id = serializers.IntegerField(label= 'ID', read_only= True)
    btitle = serializers.CharField(label= ' 名称' , max_length= 20)
    bpub_date = serializers.DateField(label= ' 发布⽇期' , required= False)
    bread = serializers.IntegerField(label= ' 阅读量' , required= False)
    bcomment = serializers.IntegerField(label= ' 评论量' , required= False)
    image = serializers.ImageField(label= ' 图⽚' , required= False)
    heroinfo_set = serializers.PrimaryKeyRelatedField(read_only= True, many= True) # 新增
    def validate_btitle( self, value):
        """单个字段验证"""
        if ' django' not in value.lower():
            raise serializers.ValidationError(" 图书不是关于Django的 " )
            return value

2.验证
                >>> from booktest.serializers import BookInfoSerializer
                >>> data = {'btitle':'python'}
                >>> s = BookInfoSerializer(data=data)
                >>> s.is_valid()
                False
                >>> s.errors
                {'btitle': [ErrorDetail(string='图书不是关于Django的', code='invalid')]}
        2.多字段联合验证
            1.提示 多字段联合验证是在单个字段验证之后进⾏的验证
            2.准备序列化器

class BookInfoSerializer(serializers.Serializer):
"""图书数据序列化器"""
    id = serializers.IntegerField(label= 'ID', read_only= True)
    btitle = serializers.CharField(label= ' 名称' , max_length= 20)
    bpub_date = serializers.DateField(label= ' 发布⽇期' , required= False)
    bread = serializers.IntegerField(label= ' 阅读量' , required= False)
    bcomment = serializers.IntegerField(label= ' 评论量' , required= False)
    image = serializers.ImageField(label= ' 图⽚' , required= False)
    heroinfo_set = serializers.PrimaryKeyRelatedField(read_only= True, many= True) # 新增
    def validate_btitle( self, value):
    """单个字段验证"""
        if ' django' not in value.lower():
            raise serializers.ValidationError(" 图书不是关于Django的 " )
            return value
    def validate(self, attrs):
        """多字段联合验证"""
        bread = attrs[ 'bread']
        bcomment = attrs[ ' bcomment' ]
        if bread < bcomment:
            raise serializers.ValidationError(' 阅读量⼩于评论量' )
            return attrs

3.验证
                为了让单个字段验证成功,btitle设置为django
                >>> from booktest.serializers import BookInfoSerializer
                >>> data = {'btitle':'django', 'bread':10, 'bcomment':20}
                >>> s = BookInfoSerializer(data=data)
                >>> s.is_valid()
                False
                >>> s.errors
                {'non_field_errors': [ErrorDetail(string='阅读量⼩于评论量', code='invalid')]}
                >>>
                'non_field_errors' 多字段联合校验时的错误信息key
        3. validators
                def about_django(value):
                    if ' django' not in value.lower():
                    raise serializers.ValidationError(" 图书不是关于Django的 " )
            1.准备序列化器

class BookInfoSerializer(serializers.Serializer):
"""图书数据序列化器"""
    id = serializers.IntegerField(label= 'ID', read_only= True)
    btitle = serializers.CharField(label= ' 名称' , max_length= 20, validators=[about_django])
    bpub_date = serializers.DateField(label= ' 发布⽇期' , required= False)
    bread = serializers.IntegerField(label= ' 阅读量' , required= False)
    bcomment = serializers.IntegerField(label= ' 评论量' , required= False)
    image = serializers.ImageField(label= ' 图⽚' , required= False)
    heroinfo_set = serializers.PrimaryKeyRelatedField(read_only= True, many= True)

2.验证
                >>> from booktest.serializers import BookInfoSerializer
                >>> data = {'btitle':'python'}
                >>> s = BookInfoSerializer(data=data)
                >>> s.is_valid()
                False
                >>> s.errors
                {'btitle': [ErrorDetail(string='图书不是关于Django的', code='invalid')]}
                >>>
    3.保存序列化器验证后的数据
        1.准备序列化器

class BookInfoSerializer(serializers.Serializer):
"""图书数据序列化器"""
    id = serializers.IntegerField(label= 'ID', read_only= True)
    btitle = serializers.CharField(label= ' 名称' , max_length= 20, validators=[about_django])
    bpub_date = serializers.DateField(label= ' 发布⽇期' , required= False)
    bread = serializers.IntegerField(label= ' 阅读量' , required= False)
    bcomment = serializers.IntegerField(label= ' 评论量' , required= False)
    image = serializers.ImageField(label= ' 图⽚' , required= False)
    heroinfo_set = serializers.PrimaryKeyRelatedField(read_only= True, many= True) # 新增
def validate_btitle( self, value):
"""单个字段验证"""
    if ' django' not in value.lower():
        raise serializers.ValidationError(" 图书不是关于Django的 " )
        return value
def validate(self, attrs):
"""多字段联合验证"""
    bread = attrs[ 'bread']
    bcomment = attrs[ ' bcomment' ]
    if bread < bcomment:
        raise serializers.ValidationError(' 阅读量⼩于评论量' )
        return attrs
def create(self, validated_data):
"""新建"""
    return BookInfo.objects.create(**validated_data)
def update(self, instance, validated_data):
"""更新,instance为要更新的对象实例"""
    instance.btitle = validated_data.get(' btitle' , instance.btitle)
    instance.bpub_date = validated_data.get(' bpub_date' , instance.bpub_date)
    instance.bread = validated_data.get('bread', instance.bread)
    instance.bcomment = validated_data.get(' bcomment' , instance.bcomment)
    instance.save()
    return instance

2.验证后保存
            说明:
            data中的数据,要让验证通过
            没有传⼊模型对象实例,所以是新增数据
            >>> from booktest.serializers import BookInfoSerializer
            >>> data = {'btitle':'django', 'bread':30, 'bcomment':10, 'bpub_date':'1989-11-11'}
            >>> s = BookInfoSerializer(data=data)
            >>> s.is_valid()
            True
            >>> book = s.save()
            >>> book
            <BookInfo: django>
    3.验证后更新
            >>> data = {'btitle':'django python', 'bread':30, 'bcomment':10, 'bpub_date':'1989-11-11'}
            >>> s = BookInfoSerializer(book, data=data)
            >>> s.is_valid()
            True
            >>> s.save()
            <BookInfo: django python>

模型类序列化器ModelSerializer
    1.模型类字段全部映射到序列化器
        1.准备序列化器
        class BookInfoModelSerializer(serializers.ModelSerializer):
        """BookInfo模型类的序列化器"""
            class Meta:
            model = BookInfo
            fields = '__all__'
        2.创建序列化器对象
            >>> from booktest.serializers import BookInfoModelSerializer
            >>> s = BookInfoModelSerializer()
            >>> s

BookInfoModelSerializer():
    id = IntegerField(label='ID', read_only=True)
    btitle = CharField(label='名称', max_length=20)
    bpub_date = DateField(label='发布⽇期')
    bread = IntegerField(label='阅读量', max_value=2147483647, min_value=-2147483648, required=False)
    bcomment = IntegerField(label='评论量', max_value=2147483647, min_value=-2147483648, required=False)
    is_delete = BooleanField(label='逻辑删除', required=False)
    image = ImageField(allow_null=True, label='图书图⽚', max_length=100, required=False)

2.模型类字段部分映射到序列化器
        1.准备序列化器
        class BookInfoModelSerializer(serializers.ModelSerializer):
        """BookInfo模型类的序列化器"""
        class Meta:
        model = BookInfo
        # fields = '__all__'
        fields = ['id', ' btitle' , ' bpub_date' ]
    2.创建序列化器对象
        >>> from booktest.serializers import BookInfoModelSerializer
        >>> s = BookInfoModelSerializer()
        >>> s
        BookInfoModelSerializer():
            id = IntegerField(label='ID', read_only=True)
            btitle = CharField(label='名称', max_length=20)
            bpub_date = DateField(label='发布⽇期')
    3.模型类字段排除指定字段
        1.准备序列化器
        class BookInfoModelSerializer(serializers.ModelSerializer):
        """BookInfo模型类的序列化器"""
            class Meta:
                model = BookInfo
                exclude = ('image',)
        2.创建序列化器对象
            >>> from booktest.serializers import BookInfoModelSerializer
            >>> s = BookInfoModelSerializer()
            >>> s

BookInfoModelSerializer():
    id = IntegerField(label='ID', read_only=True)
    btitle = CharField(label='名称', max_length=20)
    bpub_date = DateField(label='发布⽇期')
    bread = IntegerField(label='阅读量', max_value=2147483647, min_value=-2147483648, required=False)
    bcomment = IntegerField(label='评论量', max_value=2147483647, min_value=-2147483648, required=False)
    is_delete = BooleanField(label='逻辑删除', required=False)

4.嵌套
        1.准备序列化器

class HeroInfoModelSerializer(serializers.ModelSerializer):
    class Meta:
    model = HeroInfo
    fields = ['id', ' hname' , ' hbook' ]
    depth = 1 # 嵌套深度

2.创建序列化器对象
            >>> from booktest.serializers import HeroInfoModelSerializer
            >>> s = HeroInfoModelSerializer()
            >>> s

HeroInfoModelSerializer():
    id = IntegerField(label='ID', read_only=True)
    hname = CharField(label='名称', max_length=20)
    hbook = NestedSerializer(read_only=True):
    id = IntegerField(label='ID', read_only=True)
    btitle = CharField(label='名称', max_length=20)
    bpub_date = DateField(label='发布⽇期')
    bread = IntegerField(label='阅读量', max_value=2147483647, min_value=-2147483648, required=False)
    bcomment = IntegerField(label='评论量', max_value=2147483647, min_value=-2147483648, required=False)
    is_delete = BooleanField(label='逻辑删除', required=False)
    image = ImageField(allow_null=True, label='图书图⽚', max_length=100, required=False)

5.指明只读字段
        class BookInfoModelSerializer(serializers.ModelSerializer):
        """图书数据序列化器"""
            class Meta:
                model = BookInfo
                fields = ('id', ' btitle' , ' bpub_date' , 'bread', ' bcomment' )
                read_only_fields = ('id', 'bread', ' bcomment' )
    6.添加额外参数
        1.准备序列化器
        class BookInfoModelSerializer(serializers.ModelSerializer):
        """BookInfo模型类的序列化器"""
            class Meta:
                model = BookInfo
                fields = ('id', ' btitle' , ' bpub_date' , 'bread', ' bcomment' )
                extra_kwargs = {
                'bread': {'min_value': 0 , 'required': True},
                ' bcomment' : {'min_value': 0 , 'required': True},
                    }
        2.创建序列化器对象
            >>> from booktest.serializers import BookInfoModelSerializer
            >>> s = BookInfoModelSerializer()
            >>> s
        BookInfoModelSerializer():
            id = IntegerField(label='ID', read_only=True)
            btitle = CharField(label='名称', max_length=20)
            bpub_date = DateField(label='发布⽇期')
            bread = IntegerField(label='阅读量', max_value=2147483647, min_value=0, required=True)
            bcomment = IntegerField(label='评论量', max_value=2147483647, min_value=0, required=True)

视图
1.Request和Response
    1.Request
        1.介绍 Request对象的数据是⾃动根据前端发送数据的格式进⾏解析之后的结果。
        2.属性
            1 ) .data
                    request.data 返回解析之后的请求体数据。类似于Django中标准的request.POST和 request.FILES属性,但提供如下特性:
                    • 包含了解析之后的⽂件和⾮⽂件数据
                    • 包含了对POST、 PUT、 PATCH请求⽅式解析后的数据
                    • 利⽤了REST framework的 parsers解析器,不仅⽀持表单类型数据,也⽀持JSON数据
            2 ) .query_params
                    request.query_params与 Django标准的request.GET相同,只是更换了更正确的名称⽽已。
    2.Response
        1.介绍
            rest_framework.response.Response
            REST framework提供了⼀个响应类Response,使⽤该类构造响应对象时,响应的具体数据内容会被转换(render渲染)成符合前端需求的类型。
        2.渲染器
            REST framework提供了Renderer 渲染器,⽤来根据请求头中的Accept(接收数据类型声明)来⾃动转换响应数据到对应格式。
            如果前端请求中未进⾏Accept声明,则会采⽤默认⽅式处理响应数据,我们可以通过配置来修改默认响应格式。
                REST_FRAMEWORK = {
                'DEFAULT_RENDERER_CLASSES': ( # 默认响应渲染类
                'rest_framework.renderers.JSONRenderer', # json渲染器
                'rest_framework.renderers.BrowsableAPIRenderer', # 浏览API渲染器
                )
                }
        3.构造⽅法
            Response(data, status=None, template_name=None, headers=None, content_type=None)
            参数说明:
                • data: 为响应准备的序列化处理后的数据;
                • status: 状态码,默认200;
                • template_name: 模板名称,如果使⽤HTMLRenderer 时需指明;
                • headers: ⽤于存放响应头信息的字典;
                • content_type: 响应数据的Content-Type,通常此参数⽆需传递,REST framework会根据前端所需类型数据来设置该参数。
        4.属性
                1 ) .data
                        传给response对象的序列化后,但尚未render处理的数据
                2 ) .status_code
                        状态码的数字
                3 ) .content
                        经过render处理后的响应数据
        5.状态码
            为了⽅便设置状态码,REST framewrok在 rest_framework.status模块中提供了常⽤状态码常量。
            HTTP_200_OK
            HTTP_201_CREATED
            HTTP_202_ACCEPTED
            HTTP_203_NON_AUTHORITATIVE_INFORMATION
            HTTP_204_NO_CONTENT
            ......
2.DRF中类视图概览

3.使⽤APIView基类视图
    1.APIView基类视图介绍
    2.需求 使⽤APIView实现“获取所有图书信息”接⼝
    3.后端接⼝定义
        1.视图
            class BookListView(APIView):
                def get(self, request):
                """
                GET /books/
                :param request: Request类型的对象
                :return: JSON
                """
                    pass
        2.路由 # 演示APIView,实现获取所有图书信息接⼝
            url(r'^books/$', views.BookListView.as_view()),
    4.后端接⼝实现
        1.视图
            class BookListView(APIView):
                def get(self, request):
                """
                GET /books/
                :param request: Request类型的对象
                :return: JSON
                """
                    # 查询数据库
                    qs = BookInfo.objects.all()
                    # 实现序列化
                    serializer = BookInfoSerializer(qs, many= True)
                    # 响应序列化结果
                    return Response(serializer.data)
        2.序列化器
            可使⽤之前定义过的序列化器
            class BookInfoSerializer(serializers.Serializer):
                pass
            class BookInfoModelSerializer(serializers.ModelSerializer):
                pass
4.使⽤GenericAPIView基类视图
    1.GenericAPIView基类视图介绍
    2.需求
        1.使⽤GenericAPIView实现“获取所有图书信息”接⼝
        2.使⽤GenericAPIView实现“获取单⼀图书信息”接⼝
    3.实现“获取所有图书信息”接⼝
        1.视图
            class BookListView(GenericAPIView):
                # 指定查询集
                queryset = BookInfo.objects.all()
                # 指定序列化器
                serializer_class = BookInfoSerializer
                def get(self, request):
                """
                GET /books/
                :param request: Request类型的对象
                :return: JSON
                """
                    # 查询数据库
                    qs = self.get_queryset()
                    # 实现序列化
                    serializer = self.get_serializer(qs, many= True)
                    # 响应序列化结果
                    return Response(serializer.data)
        2.序列化器
            可使⽤之前定义过的序列化器
            class BookInfoSerializer(serializers.Serializer):
                pass
            class BookInfoModelSerializer(serializers.ModelSerializer):
                pass
        3.路由 # 演示APIView,GenericAPIView实现获取所有图书信息接⼝
            url(r'^books/$', views.BookListView.as_view()),
    4.实现“获取单⼀图书信息”接⼝
        1.视图
            class BookDetailView(GenericAPIView):
            # 指定查询集
            queryset = BookInfo.objects.all()
            # 指定序列化器
            serializer_class = BookInfoSerializer
            def get(self, request, pk):
            """
            GET /books/<pk>/
            :param request: Request类型的对象
            :param pk: 要访问的数据库记录
            :return: JSON
            """
            # 查询数据库:默认根据pk查询数据库单⼀结果
                book = self.get_object()
                # 实现序列化
                serializer = self.get_serializer(book)
                # 响应序列化结果
                    return Response(serializer.data)
        2.序列化器
            可使⽤之前定义过的序列化器
            class BookInfoSerializer(serializers.Serializer):
                pass
            class BookInfoModelSerializer(serializers.ModelSerializer):
                pass
        3.路由 # 演示GenericAPIView,实现获取单⼀图书信息接⼝
            url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()),
    5.使⽤Mixin扩展类
        1.Mixin扩展类介绍
        2.需求 使⽤mixins扩展类搭配GenericAPIView基类视图,实现“获取所有图书信息”接⼝
        3.实现
        class BookListView(mixins.ListModelMixin, GenericAPIView):
            # 指定查询集
            queryset = BookInfo.objects.all()
            # 指定序列化器
            serializer_class = BookInfoSerializer
            def get(self, request):
            """
            GET /books/
            :param request: Request类型的对象
            :return: JSON
            """
                return self.list(request)
    6.使⽤GenericAPIView的⼦类视图
        1.⼦类视图介绍
        2.需求 使⽤使⽤GenericAPIView的⼦类视图, 实现“获取所有图书信息”接⼝
        3.实现
            # GET /books/
                class BookListView(ListAPIView):
                    # 指定查询集
                    queryset = BookInfo.objects.all()
                    # 指定序列化器
                    serializer_class = BookInfoSerializer

相关源码连接:

github,技术交流,欢迎指教

django 学习之DRF (二)的更多相关文章

  1. Django学习笔记(二):使用Template让HTML、CSS参与网页建立

    Django学习笔记(二):使用Template让HTML.CSS参与网页建立 通过本文章实现: 了解Django中Template的使用 让HTML.CSS等参与网页建立 利用静态文件应用网页样式 ...

  2. django 学习之DRF (三)

    Django学习之DRF-03 视图集    1.视图集介绍    2.视图集基本使⽤        1.需求 使⽤视图集获取列表数据和单⼀数据        2.实现 class BookInfoV ...

  3. Django 学习笔记(二)

    Django 第一个 Hello World 项目 经过上一篇的安装,我们已经拥有了Django 框架 1.选择项目默认存放的地址 默认地址是C:\Users\Lee,也就是进入cmd控制台的地址,创 ...

  4. django 学习之DRF (一)

    Django框架基础DRF-01 前后端分离介绍 1.前后端不分离图解 2.前后端分离图解     3.为什么要学习DRF    DRF可以帮助我们开发者快速的开发⼀个依托于Django的前后后端分离 ...

  5. Django学习笔记之二

    一.使用Django自带的后端管理平台 1.后台创建管理员 python manage.py createsuperuser Email address: admin@example.com Pass ...

  6. Django学习笔记(二)视图函数

    一.url映射 1.为什么回去urls.py文件中找映射? 在‘settings.py’文件中配置了‘ROOT_URLCONF’为‘urls.py’.所有的django回去urls.py中寻找. 2. ...

  7. Django 学习笔记(二) --- HTML 模版

    人生苦短 ~ Tips:仅适用于 Python 3+(反正差别不大,py2 改改也能用).因为据 Python 之父 Guido van Rossum 说会在 2020 年停止对 Python 2 的 ...

  8. django学习笔记(二)

    上节内容回顾: 1.Django请求生命周期 -> URL对应关系(匹配) -> 视图函数 -> 返回用户字符串 -> URL对应关系(匹配) -> 视图函数 -> ...

  9. python Django 学习笔记(二)—— 一个简单的网页

    1,创建一个django项目 使用django-admin.py startproject MyDjangoSite 参考这里 2,建立视图 from django.http import HttpR ...

随机推荐

  1. HTML 5中的结构元素

    1.header:标记头部区域的内容 .footer:标记页脚区域的内容 .section:Web页面中的一块区域 4.article:独立的文章内容区域 5.aside:相关侧边内容或者引文区域 6 ...

  2. SQL命令优化

    与数据库交互的基本语言是sql,数据库每次解析和执行sql语句多需要执行很多步骤.以sql server为例,当数据库收到一条查询语句时,语法分析器会扫描sql语句并将其分成逻辑单元(如关键词.表达式 ...

  3. Git学习笔记(二)分支管理与合并及Bug分支

    一.分支管理 1.什么是分支 分支就相当于我们看科幻片里的平行宇宙,如果两个平行宇宙互不干扰,那铁定是啥事儿没有.不过,在某个时间点,两个平行宇宙合并了呢?假如两个宇宙中都有你的影子, 合并之后相当于 ...

  4. maven依赖scope配置项讲解

    我们在使用Maven配置依赖项的时候,常常只会配置Maven的坐标以及版本信息就可以了,但我们看其他人的工程代码的时候常常会见到有个scope配置项,今天就来分别介绍下这个配置下几个类别的作用. &l ...

  5. findall查找 ^$*+?{ }{m,n}[].[.] \w \s \d \b \D \W

    #!/usr/bin/env python import re r = "aasa da.5a5dfgfda ada" ret = re.findall('a',r) print( ...

  6. 全局事务/分布式事务 (Global Transaction/ A distributed transaction)之我见

    这里参考的是Oracle对于XA的支持,其他的应该雷同吧... 1个分布式事务由多个行为在不同的数据库上执行,1个分布式事务的执行成功意味着相关数据库上的行为执行均成功.“XA协定”(http://w ...

  7. 框架之 hibernate之关联关系映射

    案例:完成CRM的联系人的保存操作 需求分析 1. 因为客户和联系人是一对多的关系,在有客户的情况下,完成联系人的添加保存操作 技术分析之Hibernate的关联关系映射之一对多映射(重点) 1. J ...

  8. Blender 工具使用—–准星

    Blender 工具使用-–准星 移动准星 直接按鼠标左键 将准星放置在坐标原点 快捷键Shift + C 将准星放置到指定位置 比如下面这个位置: 按Shift + S快捷键组合,弹出一个工具栏,选 ...

  9. Linux tee命令

    一.简介 tee以标准输入作为输入,标准输出和文件作为输出.   二.语法 Usage: tee [OPTION]... [FILE]... Copy standard input to each F ...

  10. Linux bc命令

    一.简介 GNU bc是一款基于命令行的计算器程序,支持高精度数字和多种数值类型(例如二进制.十进制.十六进制)的输入输出. 二.实例 http://www.linuxidc.com/Linux/20 ...