django 学习之DRF (二)

Django学习之DRF02

Serializer序列化器之反序列化操作
    1.调?序列化器进?验证
        0.准备序列化器
            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)
        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

原文地址:https://www.cnblogs.com/x931890193/p/9330829.html

时间: 2024-11-03 14:22:06

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

Django学习笔记(二)—— 模板

疯狂的暑假学习之 Django学习笔记(二)-- 模板 参考: <The Django Book> 第四章 一.模板基础知识 1.模板是如何工作的 用 python manage.py shell 启动交互界面(因为manage.py 保存了Django的配置,如果直接python启动交互界面运行下面代码会出错) 输入下面代码 >>> from django import template >>> t = template.Template('My name

django 学习之DRF (三)

Django学习之DRF-03 视图集    1.视图集介绍    2.视图集基本使?        1.需求 使?视图集获取列表数据和单?数据        2.实现 class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet): """使?视图集实现返回列表数据和单?数据""" queryset = BookInfo.object

Django学习笔记之二

一.使用Django自带的后端管理平台 1.后台创建管理员 python manage.py createsuperuser Email address: [email protected] Password: ********** Password (again): ********* Superuser created successfully. 2.打开后台页面 http://127.0.0.1:8000/admin/ 输入刚才的用户名及密码登陆: 此时还看不到我们刚才创建的数据表 那我们

django学习笔记(二)模板

1.当模板中的变量名遇到点时,以下面的顺序查找(短路逻辑): (1)字典类型查找: >>> from django.template import Template, Context >>> person = {'name': 'Sally', 'age': '43'} >>> t = Template('{{ person.name }} is {{ person.age }} years old.') >>> c = Contex

Django学习笔记(二)App创建之Model

通过实例学习, 构建一个投票(Polls)Application, 目标结果包含两个site, 一个site用来显示投票问题以及投票结果(即将展示出来的网站), 另一个site用来管理Poll实例的增删改查(即后台内容管理CMS). 1.   创建工程 django-admin.py startproject mysite 在当前目录下, 会创建一个mysite的工程目录. 那么我们的代码放在哪里比较好呢? 可能会放到OS自带的server根目录(document root)下, 比如/var/

Python框架之Django学习笔记(二)

安装Django 我是在windows下安装的python以及django,下面的链接可以下载Django: http://www.djangoproject.com/download/ 1.下载 Django-1.6.6.tar.gz压缩文件 2.解压缩 3.在命令行下,进入Django的目录下F:\Django-1.6.6\Django-1.6.6执行python setup.py install,此时你可以喝点水等待一下. 当然,如果你很好奇: Django将被安装到你的Python安装目

Django 学习笔记之三 数据库输入数据

假设建立了django_blog项目,建立blog的app ,在models.py里面增加了Blog类,同步数据库,并且建立了对应的表.具体的参照Django 学习笔记之二的相关命令. 那么这篇主要介绍往数据库中添加数据,django默认的是sqlite3数据库. 在建立完django_blog项目后,不要忘了把 blog 加入到 settings.py 中的 INSTALLED_APPS 中. 一.同步数据库,创建相应的表 具体的参照Django 学习笔记之二的的同步数据库. 二.数据输入 下

django学习之Model(二)

继续(一)的内容: 1-跨文件的Models 在文件头部import进来,然后用ForeignKey关联上: from django.db import models from geography.models import ZipCode class Restaurant(models.Model): # ... zip_code = models.ForeignKey(ZipCode) 2-field名字的约束 1)-不能是Python预留字 2)-不能有连续的2个下划线,例如foo__ba

Django 学习笔记(七)数据库基本操作(增查改删)

一.前期准备工作,创建数据库以及数据表,详情点击<Django 学习笔记(六)MySQL配置> 1.创建一个项目 2.创建一个应用 3.更改settings.py 4.更改models.py 5.同步数据 二.安装IPython方便debug sudo apt-get install ipython3 安装成功后用python manage.py shell 会自动进入Ipython交互解释器中,没有安装Ipython只有前两行代码,只进入到Python shell 中. Python 3.5