序列化类相关

发布时间:2023年12月25日

继承APIView+Response实现 Publish的5个接口

views.py

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Publish
class PublishView(APIView):
    def get(self,request):
        publish_list=Publish.objects.all()
        l=[]
        for publish in publish_list:
            l.append({'name':publish.name,'addr':publish.addr})
        return Response({'code':100,'msg':'ok','result':l})

    def post(self,request):
        # publish=Publish.objects.create(**request.data)
        publish=Publish.objects.create(name=request.data.get('name'),addr=request.data.get('addr'))
        return Response({'code':100,'msg':'ok','result': {'name':publish.name,'addr':publish.addr}})

class PublishDetailView(APIView):
    def get(self,request,pk):
        publish=Publish.objects.filter(pk=pk).first()
        return Response({'code':100,'msg':'ok','result': {'name':publish.name,'addr':publish.addr}})

    def put(self,request,pk):
        publish = Publish.objects.filter(pk=pk).first()
        publish.name=request.data.get('name')
        publish.addr=request.data.get('addr')
        publish.save()
        return Response({'code':100,'msg':'ok','result': {'name':publish.name,'addr':publish.addr}})

    def delete(self,request,pk):
        Publish.objects.filter(pk=pk).delete()
        return Response({'code':100,'msg':'ok'})

以上代码做序列化和反序列化都是自己写的,没有做数据校验。

drf 提供的序列化器,实现? ? 序列化? ? ?反序列化? ? ?数据校验?

?使用步骤:
? ? 1 写个py文件,叫serializer.py (可以随便命名)
? ? 2 写个类,继承serializers.Serializer
? ? 3 在类中写要序列化的字段

? ? class PublishSerializer(serializers.Serializer):
? ? ? ? # 写字段,要序列化的字段
? ? ? ? name = serializers.CharField()
? ? ? ? addr = serializers.CharField()
? ? ? ? id = serializers.IntegerField()
? ? ? ??
? ? 4 在视图类中使用,完成 ?序列化
? ? ?? ?-多条
? ? ? ? ?? ?-ser = PublishSerializer(instance=publish_list, many=True)?
? ? ? ? ? ? -ser.data ?序列化后的数据
? ? ? ? -单条:
? ? ? ? ?? ?-ser = PublishSerializer(instance=publish) ??? ?
? ? ? ? ? ? -ser.data ?序列化后的数据

序列化类的使用

序列化类文件?serializer.py

from rest_framework import serializers
class PublishSerializer(serializers.Serializer):
    # 写字段,要序列化的字段
    name = serializers.CharField()
    # addr = serializers.CharField()
    id = serializers.IntegerField()

视图类 views.py

from .serializer import PublishSerializer

class PublishView(APIView):
    def get(self, request):
        publish_list = Publish.objects.all()
        ser = PublishSerializer(instance=publish_list, many=True)  # 如果序列化多条,要many=True
        return Response({'code': 100, 'msg': '查询所有成功', 'results': ser.data})

class PublishDetailView(APIView):
    def get(self, request, pk):
        publish = Publish.objects.filter(pk=pk).first()
        ser = PublishSerializer(instance=publish)  # 单个不写many=True
        return Response(
            {'code': 100, 'msg': '查询单条成功', 'results': ser.data})

路由文件 urls.py

urlpatterns = [
    path('publish/', views.PublishView.as_view()),
    path('publish/<int:pk>', views.PublishDetailView.as_view()),
]

序列化类反序列化校验

三层规则

第一层:字段自己的校验

addr=serializers.CharField(max_length=32,min_length=3)

第二层:局部钩子

def validate_addr(self,addr):
    if 'hb' in addr:
        raise ValidationError('地址中不能有hb')
    return addr

第三层:全局钩子

def validate(self,attrs):
    if attrs.get('name') == attrs.get('addr'):
        raise Exception('出版社名和地址不能一样')
    return attrs

在视图类中

def post(self,request):
    ser=PublishSerializer(data=request.data)
    if ser.is_valid(): #做三层数据校验
        print(ser.data)
    else:
        print(ser.errors)
    return Response({'code':100,'msg':'ok'})

序列化类保存

# 使用步骤:
?? ?1 在序列化类中,必须重写 create,完成真正的保存
? ? ? ?# 保存,必须重写create
? ? ? ? def create(self, validated_data):
? ? ? ? ? ? # validated_data 校验过后的数据---》多传的数据,在这没有
? ? ? ? ? ? publish = Publish.objects.create(**validated_data)
? ? ? ? ? ? return publish ?# 不要忘了返回新增的对象---》后续会拿着这个对象做序列化 ?ser.data--->根据它做序列化的
? ? 2 在视图类中,数据校验通过后,调用ser.save()
? ? ?ser.save() ?# 使用序列化类保存--》会报错---》咱们没有指定保存到那个表--》必须重写create方法?

# 修改功能,也要校验和保存

# 修改使用步骤
?? ?1 在序列化类中,必须重写 update,完成真正的修改
? ? ? ? def update(self, instance, validated_data): ?# {name:上海出版社,add:上海地址}
? ? ? ? ? ? instance.name=validated_data.get('name')
? ? ? ? ? ? instance.addr=validated_data.get('addr')
? ? ? ? ? ? instance.save() # publish 对象的save---》保存到数据中
? ? ? ? ? ? return instance
? ?2 视图类中
?? ??? ?ser = PublishSerializer(instance=publish, data=request.data)
?? ??? ?ser.save() # 虽然新增或修改都是调用save,但是内部做了判断

文章来源:https://blog.csdn.net/flclyz/article/details/135138737
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。