ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

序列化器-Serializer

2022-01-04 11:34:35  阅读:177  来源: 互联网

标签:None ser max length 序列化 data Serializer


1 序列化器-Serializer

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

2 序列化器的序列化

2.1 基本使用

2.1.1 视图层views.py

 1from django.shortcuts import render
2
3# Create your views here.
4
5
6# def test(request):
7#     request.session['name']='lqz'
8
9
10#### 查询所有图书的视图类
11from rest_framework.views import APIView
12from app01.models import Book  # 绝对导入
13
14# from .models import Book  # 相对导入,用了相对导入,当前py文件,不能以脚本形式运行
15from .serializer import BookSerializer
16from rest_framework.response import Response
17
18
19# 针对于某个表模型,总共5个接口
20# 获取所有  get
21# 获取单个  get
22# 删除单个  delete
23# 修改单个  update
24# 新增单个  post
25
26# 以后你写的所有接口(跟数据库相关),都是这个5个或这5个的变形
27class BookView(APIView):
28    def get(self, request, *args, **kwargs):
29        # 查询出所有图书
30        books = Book.objects.all()
31        # 把qs对象序列化成字典,使用序列化类完成序列化
32        # instance=None,   是要序列化的对象(可以是单个对象,可以是多个对象(放到列表或者qs对象),一定要写many=True)
33        # data=empty       反序列化的字典,目前还没用到
34        print(books)
35        ser = BookSerializer(instance=books, many=True)  # 传入要序列化的数据
36        print(ser.data)
37        # 返回给前端  ser.data 是个字典
38        # 如果是浏览器,会有一个好看的页面(注册app),如果是postman,就是json格式
39        return Response(data=ser.data)
40
41    # 新增
42    def post(self, request, *args, **kwargs):
43        # 前端传入的数据,在request.data中,是个字典
44        # 如果不使用序列化类,如何保存
45        # book=Book(title=request.data.get('title'))
46        # book.save()
47
48        # 使用序列化类做保存
49        ser = BookSerializer(data=request.data)
50        # 数据校验:如果是True,表示校验通过,直接保存
51        if ser.is_valid():
52            ser.save()  # 调用保存,但是有问题,保存不了,一定要在序列化类中重写某个方法
53            return Response(ser.data)  # 又做了一次序列化,返回给了前端
54        else:
55            return Response(ser.errors)
56
57
58class BookDetailView(APIView):
59    def get(self, request, pk):
60        # 查询某一本图书
61        books = Book.objects.all().filter(pk=pk).first()
62        ser = BookSerializer(instance=books)  # 传入要序列化的数据
63
64        return Response(data=ser.data)
65
66    def delete(self, request, pk):
67        # 跟序列化类没有关系
68        Book.objects.all().filter(pk=pk).delete()
69        return Response()
70
71    def put(self, request, pk):
72        book = Book.objects.filter(pk=pk).first()
73
74        ser = BookSerializer(instance=book, data=request.data)
75        # 数据校验:如果是True,表示校验通过,直接保存
76        if ser.is_valid():
77            ser.save()  # 调用保存,但是有问题,保存不了,一定要在序列化类中重写update方法
78            return Response(ser.data)  # 又做了一次序列化,返回给了前端

2.1.2 序列化器serializer.py

 1# 写序列化类
2from rest_framework import serializers
3from .models import Book
4from rest_framework.exceptions import ValidationError
5
6
7class BookSerializer(serializers.Serializer):  # 一定要继承一个序列化的基类
8    # 写字段,你想序列化哪个字段,就写哪个
9    title = serializers.CharField(max_length=8, min_length=3)
10    price = serializers.IntegerField()
11    # pub_date = serializers.DateField()
12
13    publish = serializers.CharField()
14
15    # 重写create,使它能够支持新增保存  (派生)
16    def create(self, validated_data):  # validated_data校验过后的数据
17        book = Book.objects.create(**validated_data)
18        return book  # 一定不要忘了return 对象,否则在视图类中用ser.data 就报错了
19
20    # 重写 update 支持修改
21    def update(self, instance, validated_data):
22        instance.title = validated_data.get('title')
23        instance.price = validated_data.get('price')
24        instance.publish = validated_data.get('publish')
25        instance.save()
26        return instance
27
28    # validate_字段名     先走字段自己的,再走局部钩子
29    def validate_title(self, item):
30        print(item)
31        # 校验字段,不能以sb开头
32        if item.startswith('sb'):
33            raise ValidationError('不能以sb开头')
34
35        return item
36
37    # 全局钩子
38    def validate(self, attrs):
39        # 校验失败,抛异常
40        if attrs.get('title') == attrs.get('publish'):
41            raise ValidationError('标题和出版社不能一样')
42
43        return attrs

2.1.3 表模型 models.py

 1from django.db import models
2
3
4# Create your models here.
5
6
7class Book(models.Model):
8    title = models.CharField(max_length=32,default='红')
9    price = models.IntegerField(default='0')
10    # pub_date = models.DateField()  # sqlite对日期的处理有问题,换成mysql
11    publish = models.CharField(max_length=32,default='出')

2.1.4 路由urls.py

1from app01 import views
2urlpatterns = [
3    path('admin/', admin.site.urls),
4    path('books/', views.BookView.as_view()),
5    path('books/<int:pk>', views.BookDetailView.as_view()),
6]

2.2 常用字段

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

2.3 常用字段参数

 1#参数名称    作用
2max_length    最大长度
3min_lenght    最小长度
4
5
6allow_blank    是否允许为空
7trim_whitespace    是否截断空白字符
8
9max_value    最小值
10min_value    最大值
11
12
13#通用参数:(针对所有字段)
14
15参数名称    说明
16#非常重要
17read_only    表明该字段仅用于序列化输出,默认False
18write_only    表明该字段仅用于反序列化输入,默认False
19
20
21
22required    表明该字段在反序列化时必须输入,默认True
23default    反序列化时使用的默认值
24allow_null    表明该字段是否允许传入None,默认False
25validators    该字段使用的验证器
26error_messages    包含错误编号与错误信息的字典

3 序列化器的反序列化

3.1 基本使用

 1 def post(self, request, *args, **kwargs):
2        # 前端传入的数据,在request.data中,是个字典
3        # 如果不使用序列化类,如何保存
4        # book=Book(title=request.data.get('title'))
5        # book.save()
6
7        # 使用序列化类做保存
8        ser = BookSerializer(data=request.data)
9        # 数据校验:如果是True,表示校验通过,直接保存
10        if ser.is_valid():
11            ser.save()  # 调用保存,但是有问题,保存不了,一定要在序列化类中重写某个方法
12            return Response(ser.data)  # 又做了一次序列化,返回给了前端
13        else:
14            return Response(ser.errors)
1 def put(self, request, pk):
2        book = Book.objects.filter(pk=pk).first()
3
4        ser = BookSerializer(instance=book, data=request.data)
5        # 数据校验:如果是True,表示校验通过,直接保存
6        if ser.is_valid():
7            ser.save()  # 调用保存,但是有问题,保存不了,一定要在序列化类中重写update方法
8            return Response(ser.data)  # 又做了一次序列化,返回给了前端

3.2 数据校验

 1# 字段自己校验规则
2title = serializers.CharField(max_length=8, min_length=3)
3
4# 局部钩子
5# validate_字段名     先走字段自己的,再走局部钩子
6    def validate_title(self, item):
7        print(item)
8        # 校验字段,不能以sb开头
9        if item.startswith('sb'):
10            raise ValidationError('不能以sb开头')
11
12        return item
13# 全局钩子
14    def validate(self, attrs):
15        # 校验失败,抛异常
16        if attrs.get('title') == attrs.get('publish'):
17            raise ValidationError('标题和出版社不能一样')
18
19        return attrs

4 模型类序列化器ModelSerializer

 1# 反序列化,正常情况不需要重写 create和update
2# 序列化:跟表模型有对应关系,不需要一个个字段都写了
3
4
5
6
7# class BookModelSerializer(serializers.ModelSerializer):
8#     # 跟某个表模型建立关系
9#     class Meta:
10#         model = Book  # 跟哪个表建立关系
11#         fields = ['title','price','id','publish']  # 要序列化哪些字段
12#         # fields = '__all__'  # 所有字段都序列化
13#
14#
15#         # 了解
16#         # exclude=['title']  # 除了某个字段外
17#         # depth=1            # 表关联
18#
19#
20#
21#         #重点
22#
23#         # read_only  只读,只序列化
24#
25#         # write_only
26#
27#     # 重写某个字段
28#     title=serializers.CharField(max_length=8,min_length=3)
29#
30#     # 局部和全局钩子跟之前一模一样
31#
32#     def validate_price(self, price):
33#         if not price>100:
34#             raise ValidationError('价格必须大于100')
35#
36#         return price
37
38
39class BookModelSerializer(serializers.ModelSerializer):
40    # 跟某个表模型建立关系
41    class Meta:
42        model = Book  # 跟哪个表建立关系
43        fields = ['title', 'price', 'id', 'publish']  # 要序列化哪些字段
44        # 重点
45        # 额外给某些字段传参数
46        # extra_kwargs = {
47        #     'title': {'max_length': 8, 'min_length': 3},
48        #     'price': {'min_value': 100}
49        # }
50
51        # read_only  只读,只序列化
52        # write_only 只写,只做反序列化,这个字段不做序列化
53        extra_kwargs = {
54            'title': {'read_only': True},
55            # 'price': {'write_only': True}
56        }

标签:None,ser,max,length,序列化,data,Serializer
来源: https://www.cnblogs.com/long4275/p/15761820.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有