DRF(二):序列化器

一 序列化器-Serializer

作用:

序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串
反序列化,把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转成模型
反序列化,完成数据校验功能

1.1 定义序列化器

Django REST framework中的Serializer使用类来定义,须继承自rest_framework.serializers.Serializer。

首先我们要有数据库模型类Publish:

from django.db import models

# Create your models here.
class Publish(models.Model):
    nid = models.AutoField(primary_key=True,verbose_name='编号')
    name = models.CharField(max_length=32,verbose_name='名称')
    city = models.CharField(max_length=32,verbose_name='所在城市')
    email = models.EmailField(verbose_name='邮箱')

    def __str__(self):
        return self.name

我们想为这个模型类提供一个序列化器,可以定义如下: 

在serializer.py中定义继承Serilizer类的PublishSerializer类。

from rest_framework import serializers


class PublishSerializer(serializers.Serializer):
    nid = serializers.IntegerField(required=False)
    name = serializers.CharField(max_length=32,error_messages={
        'max_length':'太长了,小伙子'
    })
    city = serializers.CharField()
    email = serializers.EmailField()

 注意:serializer不是只能为数据库模型类定义,也可以为非数据库模型类的数据定义。serializer是独立于数据库之外的存在。

常用字段类型

字段字段构造方式
BooleanFieldBooleanField()
NullBooleanFieldNullBooleanField()
CharFieldCharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
EmailFieldEmailField(max_length=None, min_length=None, allow_blank=False)
RegexFieldRegexField(regex, max_length=None, min_length=None, allow_blank=False)
SlugFieldSlugField(maxlength=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9-]+
URLFieldURLField(max_length=200, min_length=None, allow_blank=False)
UUIDFieldUUIDField(format=’hex_verbose’) format: 1) 'hex_verbose' 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 2) 'hex' 如 "5ce0e9a55ffa654bcee01238041fb31a" 3)'int' - 如: "123456789012312313134124512351145145114" 4)'urn' 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a"
IPAddressFieldIPAddressField(protocol=’both’, unpack_ipv4=False, **options)
IntegerFieldIntegerField(max_value=None, min_value=None)
FloatFieldFloatField(max_value=None, min_value=None)
DecimalFieldDecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits: 最多位数 decimal_palces: 小数点位置
DateTimeFieldDateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
DateFieldDateField(format=api_settings.DATE_FORMAT, input_formats=None)
TimeFieldTimeField(format=api_settings.TIME_FORMAT, input_formats=None)
DurationFieldDurationField()
ChoiceFieldChoiceField(choices) choices与Django的用法相同
MultipleChoiceFieldMultipleChoiceField(choices)
FileFieldFileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
ImageFieldImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
ListFieldListField(child=, min_length=None, max_length=None)
DictFieldDictField(child=)

选项参数:

参数名称作用
max_length最大长度
min_lenght最小长度
allow_blank是否允许为空
trim_whitespace是否截断空白字符
max_value最小值
min_value最大值

通用参数:

参数名称说明
read_only表明该字段仅用于序列化输出,默认False
write_only表明该字段仅用于反序列化输入,默认False
required表明该字段在反序列化时必须输入,默认True
default反序列化时使用的默认值
allow_null表明该字段是否允许传入None,默认False
validators该字段使用的验证器
error_messages包含错误编号与错误信息的字典
label用于HTML展示API页面时,显示的字段名称
help_text用于HTML展示API页面时,显示的字段帮助提示信息

1.2 创建Serializer对象

定义好PublishSerializer类后,就可以创建PublishSerializer对象了。

PublishSerializer的构造方法为:

PublishSerializer(instance=None, data=empty, **kwarg)

说明:

1)用于序列化时,将模型类对象传入instance参数

2)用于反序列化时,将要被反序列化的数据传入data参数

3)除了instance和data参数外,在构造PublishSerializer对象时,还可通过context参数额外添加数据,如

serializer = PublishSerializer(account, context={'request': request})

通过context参数附加的数据,可以通过PublishSerializer对象的context属性获取。

  1. 使用序列化器的时候一定要注意,序列化器声明了以后,不会自动执行,需要我们在视图中进行调用才可以。
  2. 序列化器无法直接接收数据,需要我们在视图中创建序列化器对象时把使用的数据传递过来。
  3. 序列化器的字段声明类似于我们前面使用过的表单系统。
  4. 开发restful api时,序列化器会帮我们把模型数据转换成字典.
  5. drf提供的视图会帮我们把字典转换成json,或者把客户端发送过来的数据转换字典.

1.3 序列化器的使用

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

  1. 在客户端请求时,使用序列化器可以完成对数据的反序列化。
  2. 在服务器响应时,使用序列化器可以完成对数据的序列化。

1.3.1 序列化

1.3.1.1 基本使用

1) 先查询出一个出版社对象

from app01 import models

publish = models.Publish.objects.filter(pk=id).first()

2) 构造序列化器对象

from app01 import serializer

publish_ser = serializer.PublishSerializer(instance=publish)

3)获取序列化数据

from rest_framework.views import APIView
from rest_framework.response import Response
from app01 import models
# Create your views here.
from app01 import serializer

class PublishDetailView(APIView):
    """使用序列化器序列化转换单个模型数据"""
    def get(self,request,id):
        # 获取数据
        publish = models.Publish.objects.filter(pk=id).first()
        # 数据转换[序列化过程]
        publish_ser = serializer.PublishSerializer(instance=publish)
        print(publish_ser.instance)
        # 响应数据
        return Response(publish_ser.data)

通过data属性可以获取序列化后的数据

serializer.data
# {'id': 4, 'name': '小张', 'age': 18, 'sex': True, 'description': '猴赛雷'}

完整视图代码:

4)如果要被序列化的是包含多条数据的查询集QuerySet,可以通过添加many=True参数补充说明


class PublishView(APIView):
"""使用序列化器序列化转换多个模型数据"""
    def get(self,request):
        # 获取数据
        publish_qs = models.Publish.objects.all()
        # 响应数据给客户端
        # 返回的json数据,如果是列表,则需要声明safe=False
        publish_ser = serializer.PublishSerializer(instance=publish_qs,many=True)
        return Response(publish_ser.data,safe=False)

1.3.2 通过Serializer序列化写关于出版社增删改查的接口实例。

第一步:在models.py中建好数据库模型类Publish,使用makegrations和migrate迁移命令

from django.db import models

# Create your models here.
class Publish(models.Model):
    nid = models.AutoField(primary_key=True,verbose_name='编号')
    name = models.CharField(max_length=32,verbose_name='名称')
    city = models.CharField(max_length=32,verbose_name='所在城市')
    email = models.EmailField(verbose_name='邮箱')

    def __str__(self):
        return self.name

第二步:在serializer.py中创建序列化类PublishSerializer继承Serializer

class PublishSerializer(serializers.Serializer):
    nid = serializers.IntegerField(required=False)
    name = serializers.CharField(max_length=32,error_messages={
        'max_length':'太长了,小伙子'
    })
    city = serializers.CharField()
    email = serializers.EmailField()

第三步:在views.py中创建继承APIView的视图类PublishView类和PublishDetailView类

from rest_framework.views import APIView
from rest_framework.response import Response
from app01 import models
# Create your views here.
from app01 import serializer


class PublishView(APIView):
    # get请求所有出版社信息
    def get(self,request):      
        publish_qs = models.Publish.objects.all()
        # 对所有信息进行序列化,这里many设置True
        publish_ser = serializer.PublishSerializer(instance=publish_qs,many=True)
        return Response(publish_ser.data)
    # post请求添加一条出版社数据
    def post(self,request):
        publish_ser = serializer.PublishSerializer(data=request.data)
        if publish_ser.is_valid():
            publish_ser.save()
            return Response(publish_ser.data)
        else:
            print(publish_ser.errors)
            return Response(publish_ser.errors)


class PublishDetailView(APIView):
    # get请求单条出版社信息
    def get(self,request,id):    
        publish = models.Publish.objects.filter(pk=id).first()
        publish_ser = serializer.PublishSerializer(instance=publish)
        print(publish_ser.instance)
        return Response(publish_ser.data)

    # put请求修改一条出版社信息
    def put(self,request,id):
        print(request.data)
        publish = models.Publish.objects.filter(pk=id).first()
        publish_ser = serializer.PublishSerializer(instance=publish,data=request.data)
        if publish_ser.is_valid():
            publish_ser.save()
            return Response(publish_ser.data)
        else:
            return Response('数据校验有误')

    # delete请求删除一条出版社信息
    def delete(self,request,id):
        res = models.Publish.objects.filter(pk=id).first()
        print(res)
        if res[0]>0:
            return Response('')
        else:
            return Response('要删的不存在')


第四步:在使用post请求和put请求时,数据库的数据发生了改变,所以我们需要保存序列化的数据。所以在serialzier.py的PublishSerializer类中我们需要重写create()和update()方法:

    def create(self, validated_data):
        res = models.Publish.objects.create(**validated_data)
        return res

    def update(self, instance, validated_data):

        name = validated_data.get('name')
        city = validated_data.get('city')
        email = validated_data.get('email')
        instance.name = name
        instance.city = city
        instance.email = email

        instance.save()
        return instance

第五步:在urls.py中为PublishView类和PublishDetailView类添加路由,记得在settings.py中的apps中注册rest_framework应用。

from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('publish/',views.PublishView.as_view()),
    path('publish/<int:id>',views.PublishDetailView.as_view())
]

第六步:启动django项目,在postman中输入接口地址操作数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值