序列化器-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        }
上一篇:数据结构和算法(7)


下一篇:Linux编程知识点2:进程