Serializer序列化组件使用

Serializer序列化组件使用

在models.py中定义字段(和form组件类似)
class Book(models.Model):#全部用CharField字段也可以
    id = models.AutoField(primary_key=True)#可写可不写,不写创建表时候自动生成
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)#max_digits数字最大不超过8位,其中小数部分不超过2位
    author = models.CharField(max_length=32)
    publish = models.CharField(max_length=32)

新建一个序列化py文件

# from rest_framework.serializers import Serializer
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from app01.models import Book
#校验作者名称不能以‘sb’开头或者结尾
#check_字段名
def check_author(data):  #这个函数可以写在其他的py文件中,只要能导过来
    if data.startswith('sb') or data.endswith('sb'):
        raise ValidationError('作者名字不能以“sb”开头或者结尾') #抛出错误信息
    else:
        return data
class BookSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)    #数据校验顺序是先校验id字段,是否有验证规则,(局部钩子或者全局钩子),校验完id字段后就校验name字段,校验顺序和id一样
    name = serializers.CharField(max_length=8,min_length=4)
    price = serializers.CharField(write_only=True)  #只读,序列化时候看不到该字段
    author = serializers.CharField(validators=[check_author])  #列表形式,校验作者名是否合法(可以写多个,也就是有多种校验方法)
    publish = serializers.CharField()
    def validate_price(self,data):  #validate_字段名(固定写法)  局部钩子(和form组件的钩子函数类似)
        print(data)  #这个data就是price,为str类型
        if float(data)>10:
            return data
        else:
            raise ValidationError('价格太低了')

    def validate(self, data):  #全局钩子
        print(data)
        author = data.get('author')
        publish = data.get('publish')
        if author == publish:
            raise ValidationError('作者和出版社一致了')
        else:
            return data
    """
      # form组件的钩子函数
    # 局部钩子:当你需要给单个字段增加校验规则的时候使用(校验用户名是否存在)
    def clean_username(self):
        username = self.cleaned_data.get(
            'username')
        # 去数据库校验
        is_exist = models.UserInfo.objects.filter(
            username=username)
        if is_exist:
            self.add_error('username', '用户已存在!')
        return username

    # 全局钩子:当需要给多个字段增加校验规则的时候使用(校验两次密码是否一致)
    def clean(self):
        password = self.cleaned_data.get(
            'password')
        confirm_password = self.cleaned_data.get(
            'confirm_password')
        if not password == confirm_password:
            self.add_error('confirm_password',
                           '两次密码不一致')

        return self.cleaned_data
    """

    def create(self, validated_data):  #重写create方法
        instance = Book.objects.create(**validated_data)
        return instance
    def update(self, instance, validated_data):
        #instance:创建序列化器时传入的实例对象,这里是book
        #validated_data:校验之后的数据
        #获取字段名
        # id = validated_data.get('id')
        name = validated_data.get('name')
        price = validated_data.get('price')
        author = validated_data.get('author')
        publish = validated_data.get('publish')
        #更新instance
        # instance.id = id
        instance.name = name
        instance.price = price
        instance.author = author
        instance.publish = publish
        instance.save()

        #返回instance
        return instance

class BookModelSerializer(serializers.ModelSerializer):
    #想在ModelSerializer中写局部或者全局钩子,和在Serializer中书写的一模一样
    class Meta:
        model = Book
        fields = '__all__'
        # fields = ('name','price')    #序列化name,price
        # exclude = ('name',)   #除了姓名没有序列化

        extra_kwargs = {
            'price':{'write_only':True},  #只读,运行看不到price字段
        }

在views.py中

from django.shortcuts import render
# Create your views here.
from rest_framework.views import APIView
from app01.models import Book
from app01.serialize import BookSerializer
from rest_framework.response import Response
from app01.serialize import BookModelSerializer
class BookView(APIView):#下面的class都继承(APIView)
    def get(self,request,pk):#restful根据请求方法的不同执行不同的操作
        book = Book.objects.filter(id=pk).first()
        book_serialize = BookSerializer(book)   #序列化一条,其中book为序列化的对象
        return Response(book_serialize.data)

    def put(self,request,pk):#更新数据
        back_dic = {'code':1000,'msg':''}
        book = Book.objects.filter(id=pk).first()
        boo_ser = BookSerializer(instance=book,data=request.data)#如果根据位置传参时候不要混乱位置
        if boo_ser.is_valid():#校验数据
            #保存修改,要调用序列化对象
            boo_ser.save()   #需要重写update方法(传了instance和data就触发update方法的执行)
            back_dic['msg'] = '数据校验成功'
            back_dic['data'] = boo_ser.data
        else:
            back_dic['code'] = 1001
            back_dic['msg'] = '数据校验失败'
            back_dic['data'] = boo_ser.errors
        return Response(back_dic)#定义Response对象返回字典

    def delete(self,request,pk): #删除
        Book.objects.filter(pk=pk).delete()
        return Response({'code':1000,'msg':'删除成功'})


#反序列化
class BooksView(APIView):
    def get(self,request):
        back_dic = {'code': 1000, 'msg': '数据反序列化成功'}
        books = Book.objects.all()
        books_serialize = BookSerializer(books,many=True)
        #many=True能够序列化多条数据的原因--》__new__是在__init__之前执行的,造出一个空对象
        back_dic['data'] = books_serialize.data
        return Response(back_dic)
    def put(self,request):
        back_dic = {'code':1000,'msg':''}
        book_ser = BookSerializer(data=request.data)
        #只传了data,序列化对象.sava()方法,就触发序列化create方法的执行
        if book_ser.is_valid():
            book_ser.save()
            back_dic['msg'] = '数据校验成功'
            back_dic['data'] = book_ser.data
        else:
            back_dic['code'] = 1001
            back_dic['msg'] = '数据校验失败'
            back_dic['data'] = book_ser.data
        return Response(back_dic)

#ModelSerializer
class BooksView2(APIView):
    def get(self,request):
        back_dic = {'code': 1000, 'msg': '数据反序列化成功'}
        books = Book.objects.all()
        book = Book.objects.all().first()
        books_serialize = BookModelSerializer(books,many=True)
        book_serialize = BookModelSerializer(book)
        print(type(books_serialize))
        print(type(book_serialize))
        back_dic['data'] = books_serialize.data
        return Response(back_dic)

urls.py

    # re_path('^books/(?P<pk>\d+)',views.BookView.as_view()),#删除数据和查询一条数据的路由
    # path('books/',views.BooksView.as_view()),
    # path('books2/',views.BooksView2.as_view()),
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值