首页 > 其他分享 >8.drf-序列化器

8.drf-序列化器

时间:2023-02-16 22:45:18浏览次数:46  
标签:serializers models import 序列化 data class drf

在序列化类中,如果想使用request,则可以通过self.context['request']获取

序列化器的主要由两大功能

- 对请求的数据进行校验(底层调用的是Django的Form和ModelForm)
- 对数据库查询的数据进行序列化

1.数据的校验

注意自定义的钩子函数中的参数value,对于FK或者M2M的字段,是一个对象而不是文本

 

1.1Serializer

基于Serializer类,类似Django中的Form

复制代码
import re
from rest_framework.views import APIView
from rest_framework.views import Response
from rest_framework import serializers
from django.core.validators import EmailValidator


class MyEmailValidator(object):
    def __init__(self, base):
        self.base = base

    def __call__(self, value):
        match_object = re.match(self.base, value)
        if not match_object:
            raise serializers.ValidationError('格式错误')


class UserSerializer(serializers.Serializer):
    username = serializers.CharField(label='姓名', min_length=6, max_length=32)
    age = serializers.IntegerField(label='年龄', min_value=0, max_value=200)
    level = serializers.ChoiceField(choices=((1, '董事长'), (2, '经理'), (3, '员工')))
    email1 = serializers.EmailField(label='邮箱1')
    email2 = serializers.CharField(label='邮箱2', validators=[EmailValidator, ])
    email3 = serializers.CharField(label='邮箱3')
    email4 = serializers.CharField(label='邮箱4', validators=[MyEmailValidator(r"^w+@\w+\.\w+$")])

    def validate_email3(self, value):
        "钩子函数"
        if not re.match(r"^w+@\w+\.\w+$", value):
            raise serializers.ValidationError('格式错误')
        return value


class User(APIView):
    def get(self, request):
        return Response({'code':0, 'data':'创建成功'})

    def post(self, request):
        ser = UserSerializer(data=request.data)
        if not ser.is_valid():
            return Response({'code':1006, 'data':ser.errors})
        print(ser.validated_data)
        return Response({'code':0, 'data':'创建成功'})
复制代码

 

 

1.2 ModelSerializer

基于ModelSerializer类,类似Django中的ModelForm

复制代码
import re
from rest_framework.views import APIView
from rest_framework.views import Response
from rest_framework import serializers


class UserModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = UserInfo
        # fields = '__all__'
        fields = ['username', 'age', 'email', 'password', 'level', 'depart', 'roles']




class User(APIView):
    def get(self, request):
        return Response({'code': 0, 'data': '创建成功'})

    def post(self, request):
        ser = UserModelSerializer(data=request.data)
        if not ser.is_valid():
            return Response({'code': 1006, 'data': ser.errors})
        ser.save()
        print(ser.validated_data)
        return Response({'code': 0, 'data': '创建成功'})
复制代码

 

 

 

2.序列化

通过ORM从数据库中获取QuerySet或者对象,然后序列化为json格式的数据

模型类

复制代码
from django.db import models


# Create your models here.
class Role(models.Model):
    title = models.CharField(verbose_name='名称', max_length=32)


class Department(models.Model):
    title = models.CharField(verbose_name='名称', max_length=32)


class UserInfo(models.Model):
    level_choices = ((1, '普通会员'), (2, 'VIP'), (3, 'SVIP'))
    level = models.IntegerField(verbose_name='级别', choices=level_choices, default=1)

    username = models.CharField(verbose_name='用户名', max_length=32)
    password = models.CharField(verbose_name='密码', max_length=32)
    age = models.IntegerField(verbose_name='年龄', default=18)
    email = models.CharField(verbose_name='邮箱', max_length=64)
    token = models.CharField(verbose_name='TOKEN', max_length=64, null=True, blank=True)

    depart = models.ForeignKey(verbose_name='部门', to='Department', null=True, blank=True, on_delete=models.CASCADE)
    roles = models.ManyToManyField(verbose_name='角色', to="Role")
复制代码

 

2.1 基本使用

  • 序列化的是一个queryset,则many=True

  • 序列化的是一个对象,则many=False

视图类

复制代码
from rest_framework.views import APIView
from rest_framework.views import Response
from rest_framework import serializers

from web.models import UserInfo


class UserModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserInfo
        fields = ['username', 'age', 'email']


class User(APIView):
    def get(self, request):
        """获取用户列表"""
        queryset = UserInfo.objects.all()
        ser = UserModelSerializer(instance=queryset, many=True)
        return Response({'code': 0, 'data': ser.data})
复制代码

 

 

 

2.2 自定义字段

  • 将数据库中的choice字段显示中文,如level_text

  • 将ForeignKey字段显示,如depart

  • 自定义字段,如extra,

  • 如果类中自定义的字段名和数据库的一样,则覆盖掉数据库的字段,如depart

extra = serializers.SerializerMethodField()
def get_extra(self,obj):
        return 666

 

 

复制代码
 1 from rest_framework.views import APIView
 2 from rest_framework.views import Response
 3 from rest_framework import serializers
 4 from django.core.validators import EmailValidator
 5 
 6 from web.models import UserInfo, Department, Role
 7 
 8 
 9 class UserModelSerializer(serializers.ModelSerializer):
10     level_text = serializers.CharField(source="get_level_display")
11     depart = serializers.CharField(source="depart.title")
12 
13 
14     extra = serializers.SerializerMethodField()
15     class Meta:
16         model = UserInfo
17         fields = ['username', 'age', 'email', 'level_text', 'depart', 'extra']
18 
19 
20     def get_extra(self,obj):
21         return 666
22 
23 
24 class User(APIView):
25     def get(self, request):
26         """获取用户列表"""
27 
28         queryset = UserInfo.objects.all()
29         ser = UserModelSerializer(instance=queryset, many=True)
30         return Response({'code': 0, 'data': ser.data})
复制代码

 

 

 

 

2.3 序列化的嵌套

在一个序列化类中,可以嵌套另外一个序列化类

视图

复制代码
import re
from rest_framework.views import APIView
from rest_framework.views import Response
from rest_framework import serializers
from django.core.validators import EmailValidator

from web.models import UserInfo, Department, Role

class DepartModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Department
        fields = '__all__'

class RoleModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Role
        fields = '__all__'



class UserModelSerializer(serializers.ModelSerializer):
    depart = DepartModelSerializer()
    roles = RoleModelSerializer(many=True)

    class Meta:
        model = UserInfo
        fields = ['username', 'age', 'email', 'depart', 'roles']



class User(APIView):
    def get(self, request):
        """获取用户列表"""

        queryset = UserInfo.objects.all()
        ser = UserModelSerializer(instance=queryset, many=True)
        return Response({'code': 0, 'data': ser.data})
复制代码

 

3.数据校验&序列化

有时候我们的序列化类可能既要序列化数据,也要校验数据,并且这是常有的,我们就需要给字段设置只读,只写或者可读可写来决定某个字段在序列化或者校验时是否使用本身

  • read_only= True
  • write_only = True
  • 即可读也可写

注意:

如果有嵌套的Serializer,在进行数据校验时,只有两种选择:

1. 将嵌套的序列化设置成 read_only

2. 自定义create和update方法,自定义新建和更新的逻辑

 

 

 

 

 

 

 

 

4.源码分析

4.1 类的定义

 

 

4.2 序列化

 

 

4.3 数据检验

 

 

4.4 数据保存

 

标签:serializers,models,import,序列化,data,class,drf
From: https://www.cnblogs.com/MRPython/p/17128579.html

相关文章

  • 7.drf-限流
    限流就是限制用户的访问频率,如每分钟的操作的次数不超过3次等对于匿名用户,使用用户IP作为唯一标识对于登录用户,则使用用户的ID作为唯一标识1.限流的机制DRF中......
  • 6.drf-权限
    认证:判断用户是否登陆,从而获取用户的信息权限:判断当前用户是否有权限访问API接口,例如:普通用户,管理员,超级管理员权限可能是不同的下面通过案例进行介绍模型类fromdj......
  • drf回顾,前端发展历史,vue介绍,第一个helloword,插值语法
    目录drf回顾,前端发展历史,vue介绍,第一个helloword,插值语法今日内容概要今日内容详细1drf回顾2前端发展历史3vue介绍4第一个helloworld5插值语法drf回顾,前端发展历史,vu......
  • C# 序列化 反序列化
    ///<summary>///序列化///</summary>///<paramname="obj"></param>///<returns></returns>privatestaticbyte[]?Serialize(objectobj){if(obj==n......
  • CVE-2023-0669 GoAnywhereMFT反序列化漏洞复现
    免责声明文中提到的所有技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途,否则产生的一切后果自行承担,与本文作者无关!GoAnywhereMFTGoAnywher......
  • jwt配置文件 drf-jwt源码执行流程 自定义用户实现jwt的签发和认证 simpleui 权限控制(
    昨日内容回顾#1接口文档的编写-1word,md编写---->存放位置:存放共享文件平台,git上-2第三方的接口文档编写平台-3公司自己开发,使用开源搭建yapi......
  • Jackson无法将LocalDateTime序列化成字符串的解决办法
     1.情景展示在web开发过程中,如果使用的是SpringBoot框架的话,我们通常使用在前后端数据交互的时候,我们通常会涉及到日期类型的转换。当我们需要将日期类型转换成字......
  • drf的总结与前端vue框架了解
    drf的总结与前端vue框架了解一、drf知识点整合1、drf入门及规范#1drf入门规范-前后端分离模式-前后端混合-postman-restful规范-drf:django......
  • 1 drf回顾 、2 前端发展历史、 3 vue介绍
    目录1drf回顾2前端发展历史3vue介绍1drf回顾#1drf入门规范 -前后端分离模式-前后端混合-postman-restful规范-drf:django的app#2序列化类......
  • drf入门之自动生成接口、Drf-Jwt及认证类、定制返回格式
    drf入门之自动生成接口、Drf-Jwt及认证类、定制返回格式目录drf入门之自动生成接口、Drf-Jwt及认证类、定制返回格式接口文档使用coreapi自动生成接口文档步骤jwt介绍和原......