序列化组件

序列化组件的三大功能

  1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串

  2. 反序列化,把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转成模型

  3. 反序列化时同时会完成数据校验功能

序列化器Serializer使用方法

查询单个数据语法:

1.在setting.py中的app配置里注册一下drf

image

2.在django的模型层创建一个表

from django.db import models

# Create your models here.
class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    author = models.CharField(max_length=32)

3.在表中添加一些数据

4.编写序列化组件(类似forms组件),可以在应用下单独创一个文件夹,里面放序列化组件.py

from rest_framework import serializers#  导入drf中的序列化类

# 创建一个类继承Serializer序列化类
class BookSerializer(serializers.Serializer):
    # 定义需要序列化的字段,想要哪个字段就添加该字段,不需要就注释掉
    nid = serializers.CharField()
    name = serializers.CharField()
    price = serializers.CharField()

5.在url.py中开设路径获取序列化之后的数据

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'^book/(?P<pk>d+)/$',views.BooksView.as_view()) #CBV格式的url
]

6.在视图函数中序列化需要的模型对象,返回给前端页面字典格式的数据

from rest_framework.views import APIView  # 导入drf模块的apiview,使得cbv格式的视图函数继承它
from app01 import models
from .ser import BookSerializer # 导入自己写好的序列化组件
from rest_framework.response import Response # 导入drf模块的响应类

class BooksView(APIView):
    # get请求的视图函数
    def get(self,request,pk):
        # 得到需要查询的模型对象
        book = models.Book.objects.filter(pk=pk).first()
        # 将模型对象交给自己写好的序列化器,生成一个序列化对象
        book_ser = BookSerializer(book)
        # book_ser.data 序列化对象.data就是序列化后的字典
        return Response(book_ser.data) # 利用drf中的Response类返回给前端,Response会帮您把这个字典序列化成json格式!
        # 使用JsonResponse返回上述字典,在浏览器就没有Response漂亮的格式而已,也是返回json数据格式
        return JsonResponse(book_ser.data,json_dumps_params={'ensure_ascii':False})

查询所有语法:

# views.py
class BooksView(APIView):
    def get(self,request):
        response_msg = {'status': 100, 'msg': '成功'}
        books=Book.objects.all()
        book_ser=BookSerializer(books,many=True)  #序列化多条,如果序列化一条,不需要写
        response_msg['data']=book_ser.data
        return Response(response_msg)
    
#urls.py
path('books/', views.BooksView.as_view()),

修改数据语法

1.在cbv格式的视图函数中添加put函数

    def put(self,request,pk):
        back_dic = {'code':1000,'msg':'成功'}
        # 1.得到需要查询的模型对象
        book = models.Book.objects.filter(pk=pk).first()
        # 2. 将模型对象交给自己写好的序列化器,生成一个序列化对象,除了传模型对象,还需要传入用户修改的数据
        book_ser = BookSerializer(instance=book,data=request.data)
        # 3.进行数据校验,类似forms组件的校验
        is_right = book_ser.is_valid()
        if is_right:
            # 4.校验通过操作序列化对象保存修改数据
            book_ser.save() # 注意这里需要在序列化组件中重写update()方法,否则报错
            # 5.将正确的数据在返回给前端
            back_dic['data'] = book_ser.data
        else:
            back_dic['code'] = 1001
            back_dic['msg'] = '数据格式不正确'
            back_dic['data'] = book_ser.errors
        return Response(back_dic)

2.在自定义的序列化组件类中添加update()方法

    def update(self, instance, validated_data):
        # instance参数就是book这个对象,validated_data就是用户修改提交上来的字典格式数据
        # 1.修改这个对象的字段值
        instance.name = validated_data.get('name')
        instance.price = validated_data.get('price')
        # 2.操作数据库保存修改数据
        instance.save() # 相当于book.save() 是django orm提供的方法
        # 最后需要把这个book对象在返回出去
        return instance

新增数据语法

# views.py
class BooksView(APIView):

    # 新增
    def post(self,request):
        response_msg = {'status': 100, 'msg': '成功'}
        #修改才有instance,新增没有instance,只有data
        book_ser = BookSerializer(data=request.data)
        # book_ser = BookSerializer(request.data)  # 这个按位置传request.data会给instance,就报错了
        # 校验字段
        if book_ser.is_valid():
            book_ser.save()
            response_msg['data']=book_ser.data
        else:
            response_msg['status']=102
            response_msg['msg']='数据校验失败'
            response_msg['data']=book_ser.errors
        return Response(response_msg)
#ser.py 序列化类重写create方法
    def create(self, validated_data):
        instance=Book.objects.create(**validated_data)
        return instance
# urls.py
path('books/', views.BooksView.as_view()),

删除数据语法:

# views.py
class BookView(APIView):
    def delete(self,request,pk):
        ret=Book.objects.filter(pk=pk).delete()
        return Response({'status':100,'msg':'删除成功'})
# urls.py
re_path('books/(?P<pk>d+)', views.BookView.as_view()),

序列化的字段类型

常用字段类型

# BooleanField	BooleanField()
# NullBooleanField	NullBooleanField()
# CharField	CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
# EmailField	EmailField(max_length=None, min_length=None, allow_blank=False)
# RegexField	RegexField(regex, max_length=None, min_length=None, allow_blank=False)
# SlugField	SlugField(maxlength=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9-]+
# URLField	URLField(max_length=200, min_length=None, allow_blank=False)
# UUIDField	UUIDField(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"
# IPAddressField	IPAddressField(protocol=’both’, unpack_ipv4=False, **options)
# IntegerField	IntegerField(max_value=None, min_value=None)
# FloatField	FloatField(max_value=None, min_value=None)
# DecimalField	DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits: 最多位数 decimal_palces: 小数点位置
# DateTimeField	DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
# DateField	DateField(format=api_settings.DATE_FORMAT, input_formats=None)
# TimeField	TimeField(format=api_settings.TIME_FORMAT, input_formats=None)
# DurationField	DurationField()
# ChoiceField	ChoiceField(choices) choices与Django的用法相同
# MultipleChoiceField	MultipleChoiceField(choices)
# FileField	FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
# ImageField	ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)

需要记住的字段类型

CharField
BooleanField
IntegerField
DecimalField
ListField
DictField

常用的字段参数

1 给CharField字段类使用的参数
    max_length        最长长度
    min_length        最小长度
    allow_blank       是否允许为空
    trim_whitespace   是否截断空白字段

2 给IntegerField字段类使用的参数
    max_value         最小值
    min_value         最大值

3 通用参数,放在哪个字段类上都可以
    required          表明该字段在反序列化时必须输入,默认True
    default           反序列化时使用的默认值
    allow_null        表明该字段是否允许传入None,默认False
    validators        该字段使用的验证器
    error_messages    包含错误编码与错误信息的字典
    label             用于HTML展示API页面时,显示的字段名称
    help_text         用于Html展示API页面时,显示的字段帮助提示信息

4 重点
read_only	表明该字段仅用于序列化输出,默认False,如果设置成True,postman中可以看到该字段,修改时,不需要传该字段
write_only	表明该字段仅用于反序列化输入,默认False,如果设置成True,postman中看不到该字段,修改时,该字段需要传

序列化组件中的钩子函数和validators校验

局部钩子:

    # 序列化组件中的钩子函数
    # 局部钩子函数validate_字段名的形式,需要传入一个data参数,data就是price
    def validate_price(self, data):
        print(type(data)) #格式为<class 'str'>
        print(data) # 34.00
        # 进行校验,当价格大于30报错
        if float(data) < 30:
            return data
        else:
            # 校验不通过,抛出异常 rest_framework异常在 from rest_framework.exceptions import ValidationError里
            raise ValidationError('价格太高')

全局钩子:

    def validate(self,validated_data): # validated_data校验之后的数据
        name = validated_data.get('name')
        price = validated_data.get('price')
        if name == 'zhang' and price == '25':
            raise ValidationError('不正确')
        return validated_data

第三种validators校验:

# 定义一个函数
def check_name(data):
    if data.startswith('sb'):
        raise ValidationError('名字不能是sb开头')
    else:
        return data

# 在指定字段内添加validators
name = serializers.CharField(validators=[check_name])   #validators=[]列表中写函数的内存地址

总结:主要用局部钩子和全局钩子!!

模型类序列化器

# 模型化序列器,继承ModelSerializer,并且不需要自己书写updata和create方法了
class BookSerializer2(serializers.ModelSerializer):
    # 1.定义一个Meta类
    class Meta:
        # 2.model后面等于需要序列化的表
        model = models.Book
        # 3.表示序列化该表中所有的字段
        # fields = '__all__'
        # 4.序列化表中的指定字段
        # fields = ('name','price') # 注意fields里可以放model.py里book表对应的字段,也可以放book表类里定义的方法(详解下图)
        # 5.序列化除以下字段
        exclude = ('name',) # ()里是一个元组,注意需要加个逗号
        # 6.read_only和write_only这些原本需要在字段括号内书写的参数都放在extra_kwargs里书写
        extra_kwargs = {
            'price':{'write_only':True},
        }


在book表类里加的publish_name方法,fields里放该方法,会返回该方法的返回值!
image
image

视图函数部分:

class BooksView2(APIView):
    def get(self,request):
        books = models.Book.objects.all()
        book_ser = BookSerializer2(books,many=True) # 这里改成了BookSerializer2模型化序列器
        return Response(book_ser.data)

自己封装的返回给前端的response简单版

class MyResponse(): # 这里复杂一点可以继承rest_framework的Response类
    def __init__(self): # 定义一个初始化方法,该方法有默认属性status和msg(任何由该类产生的对象都有这两个属性)
        self.status=100
        self.msg = '成功'
    
    @property # 将这个方法伪装成属性
    def get_dict(self):
        return self.__dict__ # 返回一个字典

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:序列化组件 - Python技术站

(0)
上一篇 2023年4月2日 下午4:44
下一篇 2023年4月2日

相关文章

  • 操作系统启动流程和BIOS介绍

    1.BIOS介绍 我们刚刚买回来的电脑裸机是可以直接启动的,这是由于生产厂商在电脑出厂的时候就在电脑里编写了一个只可读的系统功能BIOS,该系统被写入了ROM(只读内存中) BIOS是一个过渡性的操作系统,当安装了window等其他操作系统时,该系统会被快速的代替 2.操作系统的启动流程 1.计算机通电2.BIOS开始运行,检测硬件:cpu、内存、硬盘等3.…

    2023年4月2日
    00
  • 文章的评论(跟评论与子评论的制作)

    文章的评论制作 先做跟评论,在做子评论 发表评论框的制作:前端渲染发表评论框: {# 评论功能开始#} {% if request.user.is_authenticated %} <div> <p><span class=”glyphicon glyphicon-comment”>发表评论:</span>&l…

    2023年4月2日
    00
  • 一切皆对象和深浅拷贝

    1.元类 元类的来源是:python中一切皆对象。 1.1 什么是元类 元类就是用来实例化产生类的类 关系:元类—实例化—类(自定义的类)—实例化—-对象(obj) 1.2如何查看内置的元类 1.type是内置的元类2.我们用class关键字定义出来的所有类以及内置的类都是由内置的元类type实例化产生的 例如:在python中int、dic…

    2023年4月2日
    00
  • 小程序子页面向父页面传值、腾讯云对象存储上传图片

    1. 页面传值 1.1 父页面向子页面传值 父页面: /pages/xx/xxx?id=1 子页面 // option就可以接收到父页面传来的值 onLoad:function(option){ } 1.2 子父页面 子页面 var pages = getCurrentPages() var prevPage = pages[pages.length-2] …

    Python开发 2023年4月2日
    00
  • IO模型

    该篇的IO模型主要针对的是网络IO的,其他IO不在本篇考虑范围之内! IO模型简介 Stevens在文章中一共比较了五种IO Model,分别为: * blocking IO 阻塞IO * nonblocking IO 非阻塞IO * IO multiplexing IO多路复用 * signal driven IO 信号驱动IO * asynchronou…

    2023年4月2日
    00
  • 自动生成路由和action的使用

    自动生成路由 普通cbv视图形式的路由: path(‘books4/’, views.Book4View.as_view()), re_path(‘books4/(?P<pk>\d+)’, views.Book4DetailView.as_view()) 继承了ViewSetMixin及其子类的视图路由: path(‘books5/’, view…

    Python开发 2023年4月2日
    00
  • django中的cookie、session和token

    发展史 1.早期的时候,网站都没有保存用户功能的需求,所有用户访问网站返回的结果都是一样的,比如新闻、文章等网站! 2.但是,随着网站的发展,出现了一些需要保存用户信息的网站,比如:淘宝、京东、个人博客等! 3.以登录功能为例,如果不保存用户登录的信息,就意味着用户每次都需要重新登录网站,为此非常的麻烦。 4.为了解决上述的麻烦,便产生了cookie和ses…

    2023年4月2日
    00
  • 函数的递归

    1.函数的递归的定义 函数的递归调用:是函数嵌套调用的一种特殊形式 具体是指:在调用一个函数的过程中又直接或者间接的调用到本身,是一个死循环,最大递归是1000次,超出之后报错。 2.函数递归的调用 # 直接调本身 def f1(): print(‘是我还是我’) f1() f1() # 间接调用 def f1(): print(‘f1’) f2() def…

    Python开发 2023年4月2日
    00
合作推广
合作推广
分享本页
返回顶部