• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    drf序列化器serializer的具体使用

    一、序列化器-serializer

    二、序列化器的使用

    序列化器的使用分为两个阶段:

    简单使用

    1、创建一个表模型

    from django.db import models
    
    class Books(models.Model):
        title = models.CharField(verbose_name='书名', max_length=32)
        publish = models.CharField(verbose_name='出版社', max_length=32)
        price = models.DecimalField(verbose_name='价格', max_digits=5, decimal_places=2)
    
    

    2、新建一个py文件,写一个序列化的类,继承Serializer

    3、在类中写要序列化的字段,想序列化那个字段,就在类中写那个字段

    from rest_framework import serializers
    
    class BooksSerializer(serializers.Serializer):
        title = serializers.CharField()
        publish = serializers.CharField()
        price = serializers.DecimalField()
    
    

    4、在视图类中使用,导入——》实例化得到序列化对象,把要序列化的对象传入

    5、序列化的对象.data——》是一个字典

    6、把字典返回,如果不使用rest_framework提供的Response,就得使用JsonResponse

    from rest_framework.views import APIView
    from rest_framework.request import Request
    from app01.models import Books
    from app01.ser import BooksSerializer
    
    class BookView(APIView):
        def get(self, request, pk):
            # 响应信息
            response_msg = {'status': 200, 'message': '查询成功'}
            # 获取要序列化的对象
            book = Books.objects.filter(pk=pk).first()
            # 要序列化谁就把谁传到序列化类去
            book_ser = BooksSerializer(book)
            # book_ser.data————》序列化对象.data————》就是序列化后的字典
            # 将查询结果添加到响应信息内
            response_msg['data'] = book_ser.data
            return Response(response_msg)
        
     # urls.py
    re_path(r'^book/(?Ppk>\d+)/', views.BookView.as_view()),
    
    

    7、如果要被序列化的是包含多条数据的查询集queryset,可以通过添加many=True参数

    from rest_framework.views import APIView
    from rest_framework.response import Response
    from app01.models import Books
    from app01.ser import BooksSerializer
    
    
    class BooksView(APIView):
        def get(self, request):
            # 响应信息
            response_msg = {'status': 200, 'message': '查询成功'}
            books = Books.objects.all()
            # 要序列化谁就把谁传到序列化类去
            book_ser = BooksSerializer(books, many=True)
            # book_ser.data————》序列化对象.data————》就是序列化后的字典
            # 将查询结果添加到响应信息内
            response_msg['data'] = book_ser.data
            return Response(response_msg)
    
    # urls.py
    re_path(r'^books/', views.BookView.as_view()),
    
    

    高级使用

    source

    1、可以修改字段名字

    class BooksSerializer(serializers.Serializer):
        xxx = serializers.CharField(source='title')  # 相当于——》xxx = Books.title
          
    # 响应
    {
        "status": 200,
        "message": "查询成功",
        "data": {
            "xxx": "魔道祖师"   ————》响应的字段名被修改了
        }
    }

    2、可以跨表查询

    class BookSerializer(serializers.Serializer):
        publish_email = serializers.CharField(source='publish.email')
        # 相当于——》publish_email = Book.publish.email 连表查询publish表的email字段
        
        
    # 响应
    {
        "status": 200,
        "message": "查询成功",
        "data": {
            "publish_email": "modao@163.com"
        }
    }
    

    3、可以执行方法

    # models.py
    class Book(models.Model):
        title = models.CharField(max_length=32)
        price = models.IntegerField()
        pub_date = models.DateTimeField()
        publish = models.ForeignKey("Publish", on_delete=models.CASCADE, null=True)
        authors = models.ManyToManyField("Author")
    
        def func(self):
            return '666666'
    
        
    # ser.py
    class BookSerializer(serializers.Serializer):
        msg = serializers.CharField(source='func')
        # msg = Book.func  ——》调用Book类中的func()方法的返回值
        
        
    # 响应
    {
        "status": 200,
        "message": "查询成功",
        "data": {
            "msg": "666666"
        }
    }

    **SerializerMethodField( ) **

    它需要有一个配套的方法,方法名叫做get_字段名,返回值就是要显示的东西

    class BookSerializer(serializers.Serializer):
        authors = serializers.SerializerMethodField()
    
        def get_authors(self, instance):
            # instance ——》 Book对象
            authors = instance.authors.all()    # 取出所有作者
            author_list = []
            for author in authors:
                author_list.append({'name': author.name, 'age': author.age})
            return author_list
    
    

    通用参数

    read_only:(只读)表明该字段仅用于序列化输出,默认False,如果设置成True,响应中可以看到该字段,修改时,不需要传该字段

    write_only:(只写)表明该字段仅用于反序列化输入,默认False,如果设置成True,响应中看不到该字段,修改时,该字段需要传

    from rest_framework import serializers
    
    class BooksSerializer(serializers.Serializer):
        title = serializers.CharField(read_only = True)  # 响应中能看到改字段,修改不需要传值
        publish = serializers.CharField(write_only = True) # 响应中看不到改字段,修改需要传值
        price = serializers.DecimalField()

    还有参数如下:

    三、反序列化数据校验

    当使用序列化器对数据进行反序列化时,就需要对数据进行校验了,只有校验成功的数据才能被保存成模型类对象

    将要校验的数据传入序列化器中并实例化:obj = BooksSerializer(data=request.data),调用is_valid()方法校验,校验成功返回True,失败返回False。

    失败,可以通过序列化器对象的errors获取错误信息(字典)

    成功,可以公共序列化对象的validated_data属性获取数据。

    校验方法有:局部钩子,全局钩子,validators,和序列化类型和字段属性也是

    字段属性

    局部钩子

    在序列化器类中创建局部钩子:validate_字段名,并且接收一个参数

    # ser.py
    class BooksSerializer(serializers.Serializer):
        title = serializers.CharField()
        publish = serializers.CharField()
        price = serializers.DecimalField(max_digits=5, decimal_places=2)
        
        # 局部钩子对price字段校验
        def validate_price(self, data):
            if float(data) > 20:
                # 校验成功就通过
                return data
            else:
                # 校验失败就抛异常
                raise ValidationError('价格太低')
    

    全局钩子

    全局钩子:validate( ), 接收一个参数,

    同时对多个字段进行比较验证

    # ser.py
    class BooksSerializer(serializers.Serializer):
        title = serializers.CharField()
        publish = serializers.CharField()
        price = serializers.DecimalField(max_digits=5, decimal_places=2)
        
    def validate(self, validate_data):
        title = validate_data.get('title')
        publish = validate_data.get('publish')
        if not title == publish:
            return validate_data
        else:
            raise ValidationError('书名和出版社不能一致')
    

    validators

    使用字段的validators=[func],来校验

    # ser.py
    # 校验函数
    def check_price(data):
        if float(data) > 10:
            return data
        else:
            raise ValidationError('价格太低')
    
    class BooksSerializer(serializers.Serializer):
        title = serializers.CharField()
        publish = serializers.CharField()
        price = serializers.CharField(validators=[check_price]) # 配置

    四、序列化器操作数据

    查询所有

    # views.py
    class BooksView(APIView):
        def get(self, request):
            # 响应信息
            response_msg = {'status': 200, 'message': '查询成功'}
            # 获取所有数据
            books = Books.objects.all()
            # 把数据谁传到序列化器中
            book_ser = BooksSerializer(instance=books, many=True) # 序列化多条需要加 many=True
            # book_ser.data————》序列化对象.data————》就是序列化后的字典
            # 将查询结果添加到响应信息内
            response_msg['data'] = book_ser.data
            return Response(response_msg)
        
    # urls.py
    path('books/', views.BooksView.as_view()),
    

    查询单条

    # views.py
    class BookView(APIView):
        def get(self, request, pk):
            # 响应信息
            response_msg = {'status': 200, 'message': '查询成功'}
            # 获取要序列化的对象
            book = Books.objects.filter(pk=pk).first()
            # 要序列化谁就把谁传到序列化器中
            book_ser = BooksSerializer(instance=book)
            # book_ser.data————》序列化对象.data————》就是序列化后的字典
            # 将查询结果添加到响应信息内
            response_msg['data'] = book_ser.data
            return Response(response_msg)
        
    # urls.py
    re_path(r'^book/(?Ppk>\d+)/', views.BookView.as_view()),
    

    新增数据

    新增数据需要在序列化器中重写create( ) 方法:

    注意没有传递instance实例,则调用save()方法的时候,create()被调用,相反,如果传递了instance实例,调用save()方法的时候,update()被调用。

    # views.py
    class BookView(APIView):
        def post(self, request):
            # 响应信息
            response_msg = {'status': 201, 'message': '增加成功'}
            # 修改才有instance,新增没有instance,只有data
            book_ser = BooksSerializer(data=request.data)
    
            # 校验字段
            if book_ser.is_valid():
                book_ser.save()  # 需要在序列化器中重写create()方法
                # 保存成功把原数据返回
                response_msg['data'] = book_ser.data
            else:
                response_msg['status'] = 202
                response_msg['message'] = '数据校验失败'
                response_msg['data'] = book_ser.error_messages
            return Response(response_msg)
        
        
    # ser.py
    class BooksSerializer(serializers.Serializer):
        title = serializers.CharField()
        publish = serializers.CharField()
        price = serializers.DecimalField(max_digits=5, decimal_places=2)
    
        # 重写create
        def create(self, validated_data):   # validated_data——>传入的新增数据
            instance = Books.objects.create(**validated_data)
            # instance——> 新增的字段对象,需要返回
            return instance
           
    # urls.py
    path('book/', views.BookView.as_view()),

    修改数据

    修改数据需要在序列化器中重写update( ) 方法:

    # views.py
    class BookView(APIView):
        def put(self, request, pk):
            # 响应信息
            response_msg = {'status': 200, 'message': '修改成功'}
            # 获取需要修改的字段对象
            book = Books.objects.filter(pk=pk).first()
            # 将字段对象和修改数据添加到序列化器中
            book_ser = BooksSerializer(instance=book, data=request.data)
    
            # 校验数据
            if book_ser.is_valid():
                book_ser.save()     # 需要在序列化器中重写update()方法
                response_msg['data'] = book_ser.data
            else:
                response_msg['status'] = 202
                response_msg['message'] = '数据校验失败'
                response_msg['data'] = book_ser.error_messages
            return Response(response_msg)
        
    # urls.py
    re_path('book/(?Ppk>\d+)', views.BookView.as_view()),

    删除数据

    # views.py
    class BooksView(APIView):
        def delete(self, request, pk):
        # 响应信息
        response_msg = {'status': 200, 'message': '删除成功'}
        # 删除数据
        Books.objects.filter(pk=pk).delete()
        return Response(response_msg)
        
    # urls.py
    re_path('book/(?Ppk>\d+)', views.BooksView.as_view()),
    

    五、模型类序列化器

    DRF提供了ModelSerializer模型类序列化器来帮助我们快速创建一个Serializer类。

    ModelSerializer与常规的Serializer相同,但是提供了:

    实例:

    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            model = Book        # 指明参照那个模型类
            fields = '__all__'  # 为模型类的那些字段生成
    

    字段操作

    1、可以使用fields来明确字段,__all__表示包含所以字段,具体那些字段->fields = ('title','price')

    2、exclude表示排除那些字段,不能和fields一起写——>exclude = ('price',)

    3、额外参数extra_kwargs,给字段添加额外的参数

    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            model = Book        # 指明参照那个模型类
            fields = '__all__'  # 为模型类的那些字段生成
      
            # 类似于  title = serializers.CharField(read_only = True)
            extra_kwargs = {
                'title': {'read_only': True},
            }
    

    六、源码分析many=True

    当我们需要查询多条数据时就需要在实例化序列化器的时候传many=True

    book_ser = BooksSerializer(instance=books, many=True) # 查询多条
    book_one_ser = BooksSerializer(instance=book) # 查询单条
    
    print(type(book_ser))
    #class 'rest_framework.serializers.ListSerializer'>
    
    print(type(book_one_ser))
    #class 'app01.ser.BookModelSerializer'>
    
    # 对象的生成-->先调用类的__new__方法,生成空对象,如果many=True,生成ListSerializer对象,反之生成Serializer对象
    
    # 类的__new__方法控制对象的生成
    def __new__(cls, *args, **kwargs):
        # 如果many=True,就会自动创建ListSerializer类
        if kwargs.pop('many', False):
            return cls.many_init(*args, **kwargs)
        return super().__new__(cls, *args, **kwargs)
    
    

    到此这篇关于drf序列化器serializer的具体使用的文章就介绍到这了,更多相关drf序列化器serializer内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    您可能感兴趣的文章:
    • DRF跨域后端解决之django-cors-headers的使用
    • django DRF图片路径问题的解决方法
    • Django框架之DRF 基于mixins来封装的视图详解
    • DRF使用simple JWT身份验证的实现
    • Django DRF APIView源码运行流程详解
    • python drf各类组件的用法和作用
    • DRF框架API版本管理实现方法解析
    • Django drf请求模块源码解析
    上一篇:Django REST framework 异常处理
    下一篇:python+opencv+selenium自动化登录邮箱并解决滑动验证的问题
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    drf序列化器serializer的具体使用 drf,序列化,器,serializer,的,