DRF框架 序列化

DRF框架 序列化,第1张

DRF框架 序列化 简介

DRF(Django REST framework)是构建RESTful风格的Web api的强大而灵活的工具包。它是在Django框架基础之上,进行了二次开发。简称为DRF框架或REST framework框架。

特性
  • 提供了强大的Serializer序列化器, 可以高效地进行序列化与反序列化 *** 作
  • 提供了极为丰富的类视图、Mixin扩展类、ViewSet视图集
  • 提供了直观的Web API界面
  • 多种身份认证和权限认证
  • 强大的排序、过滤、分页、搜索、限流等功能
  • 可扩展性,插件丰富
安装
pip install djangorestframework

将 rest_framework 添加到INSTALLED_APPS设置中:

INSTALLED_APPS = [
    'rest_framework',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
序列化器的基本使用

序列化器 — Serializer
drf框架最大的特点就是它序列化器,其作用如下:

  • 将模型对象序列化为字典,将来提供给视图经过response以后成为json字符串。
  • 将客户端发送过来的数据经过视图调用request成为python字典,序列化器可以把字典转换成模型。
  • 完成数据库校验和 *** 作数据库功能
定义序列化器

继续使用前面已创建的学生表来演示序列化器的基本使用

from django.db import models

class Student(models.Model):
    """
    学生表
    """
    name = models.CharField('学生姓名', max_length=200, unique=True, help_text='学生姓名')
    gender = models.SmallIntegerField('性别', default='1', help_text='性别')
    hobby = models.CharField('爱好', max_length=200, null=True, blank=True, help_text='兴趣爱好')
    age = models.IntegerField('年龄', null=True, )
    create_time = models.DateTimeField('创建时间', auto_now_add=True, help_text='创建时间')
    grade = models.ForeignKey('Grade', on_delete=models.SET_NULL, null=True, related_name='students')  # 设置外键,级联删除)

    class meta:
        """
        元数据,
        """
        db_table = 'student'  # 指定当前模型创建的表明,不写默认当前的模型名Student
        verbose_name = '学生信息表'  # 注释
        verbose_name_plural = verbose_name  # 指定为复数

在应用目录下创建serializers.py文件,定义类并继承rest_framework.serializers.Serializer,类似于模型,定义这个序列化器是为了序列化项目对象,所以字段与模型中的字段一一对应。

from rest_framework import serializers


class ProjectSerializer(serializers.Serializer):
    """
    项目序列化器
    """
    id = serializers.IntegerField(label='学生id', read_only=True) # 只读
    name = serializers.CharField(label='学生姓名')
    hobby = serializers.CharField(label='兴趣爱好',allow_null=True,required=False) # allow_null允许接收null,required=False实例化对象时可以忽略此字段
    age = serializers.IntegerField(label='年龄')
    c_time = serializers.DateTimeField(label='创建时间', read_only=True)
使用序列化器

一、序列化模型实例

In [12]: from projects.models import *
In [13]: from projects.serializers import ProjectSerializer

In [14]: s=Student.objects.first() # 实例化一个对象
In [15]: p = ProjectSerializers(s) # 通过序列化器转换为字典
In [16]: p.data
Out[17]: {'id': 3, 'name': 'test3', 'hobby': '玩游戏', 'age': 19}

为了完成序列化过程,还要将其转化为json,需要导入

Out[17]: from rest_framework.renderers import JSonRenderer
In [18]: JSONRenderer().render(p.data)
Out[18]: b'{"id":3,"name":"test3","hobby":"xe7x8exa9xe6xb8xb8xe6x88x8f","age":19}'

二、序列化查询集
使用序列化器时指定many参数等于True

In [22]: s1 = Student.objects.all()

In [23]: p1 = ProjectSerializers(s1)
 
In [25]: p1.data

In [26]: p1 = ProjectSerializers(s1,many=True)

In [27]: p1.data 

Out[27]: [OrderedDict([('id', 3), ('name', 'test3'), ('hobby', '玩游戏'), ('age', 19)]), OrderedDict([('id', 4), ('name', '张三'), ('hobby', '玩'), ('age', 21)]), OrderedDict([('id', 5), ('name', 'zhaom'), ('hobby', 'play'), ('age',
112)]), OrderedDict([('id', 8), ('name', '阿三'), ('hobby', 'play'), ('age', 22)]), OrderedDict([('id', 9), ('name', 'test2'), ('hobby', 'wan'), ('age', 10)]), OrderedDict([('id', 13), ('name', 'ls'), ('hobby', None), ('age', 33)]),
OrderedDict([('id', 14), ('name', 'laa'), ('hobby', None), ('age', 35)]), OrderedDict([('id', 15), ('name', 'aa'), ('hobby', 'con'), ('age', 36)]), OrderedDict([('id', 16), ('name', 'ceaaa'), ('hobby', '11'), ('age', 1111)]), Ordered
Dict([('id', 17), ('name', '111'), ('hobby', ''), ('age', 222)]), OrderedDict([('id', 18), ('name', 'test33'), ('hobby', '打篮球'), ('age', 99)]), OrderedDict([('id', 21), ('name', 'test'), ('hobby', '打篮球'), ('age', 991)])]

In [28]: JSONRenderer().render(p1.data)

Out[28]: b'[{"id":3,"name":"test3","hobby":"xe7x8exa9xe6xb8xb8xe6x88x8f","age":19},{"id":4,"name":"xe5xbcxa0xe4xb8x89","hobby":"xe7x8exa9","age":21},{"id":5,"name":"zhaom","hobby":"play","age":112},{"id":8,"name":"
xe9x98xbfxe4xb8x89","hobby":"play","age":22},{"id":9,"name":"test2","hobby":"wan","age":10},{"id":13,"name":"ls","hobby":null,"age":33},{"id":14,"name":"laa","hobby":null,"age":35},{"id":15,"name":"aa","hobby":"con","age":36},{"
id":16,"name":"ceaaa","hobby":"11","age":1111},{"id":17,"name":"111","hobby":"","age":222},{"id":18,"name":"test33","hobby":"xe6x89x93xe7xafxaexe7x90x83","age":99},{"id":21,"name":"test","hobby":"xe6x89x93xe7xafxaexe7
x90x83","age":991}]'
反序列化

反序列化的过程与序列化类似,先将序列化数据(json)解析为原生python数据类型(省略),然后将其填充到一个序列化器对象中。

In [29]: data ={"name":"test111","hobby":"喝酒","age":44}

In [30]: p = ProjectSerializers(data=data)

In [31]: p.is_valid() # 校验
Out[32]: True
In [33]: s.validated_data # 校验后的数据
Out[34]: OrderedDict([('name', 'test111'), ('hobby', '喝酒'), 

在调用save()方法之前,还需要实现两个方法来完成模型实例的创建和修改,在ProjectSerializer类中重写父类中的create与update方法:

from rest_framework import serializers
from project2s.models import Student

class ProjectSerializers(serializers.Serializer):
    """
    项目序列化器
    """
    id = serializers.IntegerField(label='学生id', read_only=True)
    name = serializers.CharField(label='学生姓名')
    hobby = serializers.CharField(label='兴趣爱好', allow_null=True, required=False)  # 允许接收null,required=False实例化对象时可以忽略此字段
    age = serializers.IntegerField(label='年龄')
    c_time = serializers.DateTimeField(label='创建时间', read_only=True)

    def create(self, validated_data):
   
        return Student.objects.create(**validated_data) # 返回一个新对象

    def update(self, instance, validated_data):
        for key, value in validated_data.items():
            setattr(instance, key, value)
        instance.save()
        return instance
In [35]: s.save() # 序列化器实例可以调用save()直接返回一个模型实例
Out[36]: 

当数据校验未通过时,可以通过errors查看具体信息:
举例 :
name字段不传,校验结果为False

In [9]:  data ={"name":"","hobby":"喝酒","age":44}

In [10]: p1 = ProjectSerializers(data=data)

In [11]: p1.is_valid()
Out[11]: False

In [12]: p1.error_messages
Out[12]: 
{'required': '该字段是必填项。',
 'null': '该字段不能为 null。',
 'invalid': '无效数据。期待为字典类型,得到的是 {datatype} 。'}

In [13]: p1.errors
Out[13]: {'name': [ErrorDetail(string='该字段不能为空。', code='blank')]}
模型序列化器

我们的ProjectSerializer类复制了大量Project模型中的的信息。RESTframework提供了一个ModelSerializer,它可以根据模型自动创建Serializer类,使代码更简洁。

from rest_framework import serializers
from project2s.models import Student

class ProjectSerializers(serializers.ModelSerializer):
    class meta:
        model = Student # 指定模型
        fields = ['id', 'name', 'hobby', 'age'] # 指定需要序列化的字段

可以通过打印序列化器实例的表示形式来检查它的所有字段:

In [1]: from project2s.serializers import *

In [2]: s = ProjectSerializers()

In [3]: s
Out[3]: 
ProjectSerializers():
    id = IntegerField(label='ID', read_only=True)
    name = CharField(help_text='学生姓名', label='学生姓名', max_length=200, validators=[])
    hobby = CharField(allow_blank=True, allow_null=True, help_text='兴趣爱好', label='爱好', max_length=200, required=False)
    age = IntegerField(allow_null=True, label='年龄', max_value=2147483647, min_value=-2147483648, required=False)

ModelSerializer类只是创建serializer类的一个快捷方式,自动确定的字段,create()和update()方法的简单默认实现。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5579100.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存