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":"\xe7\x8e\xa9\xe6\xb8\xb8\xe6\x88\x8f","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":"\xe7\x8e\xa9\xe6\xb8\xb8\xe6\x88\x8f","age":19},{"id":4,"name":"\xe5\xbc\xa0\xe4\xb8\x89","hobby":"\xe7\x8e\xa9","age":21},{"id":5,"name":"zhaom","hobby":"play","age":112},{"id":8,"name":"\
xe9\x98\xbf\xe4\xb8\x89","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":"\xe6\x89\x93\xe7\xaf\xae\xe7\x90\x83","age":99},{"id":21,"name":"test","hobby":"\xe6\x89\x93\xe7\xaf\xae\xe7
\x90\x83","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]: <Student: name:test111,hobby:喝酒>

当数据校验未通过时,可以通过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=[<UniqueValidator(queryset=Student.objects.all())>])
    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()方法的简单默认实现。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
DRF(Django Rest Framework)是一种用于构建Web API的强大框架,它提供了丰富的功能和工具来简化API的开发过程。在使用DRF时,我们经常需要定义视图和序列化器以及它们之间的关系来处理不同的请求和操作。 DRF的请求处理基于视图的操作方法,它们分别对应于HTTP方法,例如GET,POST,PUT,PATCH和DELETE。这些操作方法在视图中以函数的形式定义,并且通过装饰器或路由来映射到相应的URL。 序列化器是DRF的一个核心概念,它提供了一种简单而灵活的方式,将数据对象转换为可以被序列化和反序列化的格式,通常是JSON或XML。序列化器可以定义在视图中,也可以单独定义为一个类,然后在视图中使用。 在DRF中,我们可以通过定义不同的序列化器类来处理不同的操作。序列化器类可以继承自DRF提供的Serializer类或ModelSerializer类,后者自动为我们根据模型生成序列化器字段。 使用序列化器,我们可以在视图中方便地对请求进行验证、数据转换和结果序列化等操作。在视图的操作方法中,我们可以通过调用序列化器的不同方法来进行这些操作。 例如,我们可以使用序列化器的`is_valid()`方法来验证请求的数据是否有效。我们还可以使用`save()`方法来保存数据,或者使用`data`属性来获取序列化后的数据。此外,我们还可以通过调用`serializer_class()`方法来获取当前视图使用的序列化器类。 总之,DRF的action序列化提供了一种方便而强大的方式来处理API的请求和操作。通过定义视图和序列化器,并将它们联系起来,我们可以在开发API时更加高效和灵活。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

久醉绕心弦,

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值