目录
drf序列化器
我们在编写接口的时候需要对数据进行序列化与反序列化。而且反序列化过程中还要做数据校验。
drf给我们提供了固定的写法.
提供了两序列化个类
1.Serializer
2.ModelSerializer
继承drf提供的序列化类使用其中的方法就可以完成序列化与反序列化并在反序列化过程中校验数据。
练习
1.使用APIView 序列化类 Response完成接口的编写
models
from django.db import models
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32)
urls
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('books/',views.BookView.as_view()),
path('books/<int:pk>/',views.BookDetailView.as_view())
]
serializer
# 导入序列化类,反序列化时进行校验
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.Serializer):
# 序列化字段
name = serializers.CharField()
price = serializers.CharField()
def create(self, validated_data):
# validated_data 就是校验过的数据
# 保存
book = Book.objects.create(**validated_data)
return book
def update(self, instance, validated_data):
instance.name = validated_data.get('name')
instance.price = validated_data.get('price')
instance.save() # instance是个对象,对象可以一直点对象的方法
return instance
views
from django.shortcuts import render
# Create your views here.
from rest_framework.views import APIView
from .models import Book
from rest_framework.views import Response
from .serializer import BookSerializer
class BookView(APIView):
def get(self, request):
books = Book.objects.all()
# 使用序列化类完成,instance参数就是需要序列化的queryset对象,many多个就传True默认None
ser = BookSerializer(instance=books, many=True)
return Response(ser.data)
# 新增一个
def post(self, request):
# 把数据传入序列化类
ser = BookSerializer(data=request.data)
# 校验数据
if ser.is_valid():
# 保存,需要在序列化类中自己写create方法
ser.save() # 调用save会自动触发create
"查看save内部源码发现内部的if判断通过我们传的参数判断是保存还是更新"
return Response({'code': 100, 'msg': '新增成功', 'result': ser.data})
else:
return Response({'code': 101, 'msg': ser.errors})
class BookDetailView(APIView):
# 查询一个
def get(self,request,*args,**kwargs):
book = Book.objects.filter(pk=kwargs.get('pk')).first()
ser = BookSerializer(instance=book)
return Response(ser.data)
# 修改一个
def put(self,request,*args,**kwargs):
book = Book.objects.filter(pk=kwargs.get('pk')).first()
#反序列化保存
ser = BookSerializer(data=request.data,instance=book)
if ser.is_valid():
ser.save()
return Response({'code':100,'msg':'修改成功','result':ser.data})
else:
return Response({'code':101,'msg':ser.errors})
# 删除一个
def delete(self,request,pk):
Book.objects.filter(pk=pk).delete()
return Response({'code':100,'msg':'删除成功'})
反序列化的校验
序列化类中也可以填写局部钩子与全局钩子
# 导入序列化类,反序列化时进行校验
from rest_framework import serializers
from .models import Book
from rest_framework.exceptions import ValidationError
class BookSerializer(serializers.Serializer):
# 序列化字段
name = serializers.CharField()
price = serializers.CharField()
def create(self, validated_data):
# validated_data 就是校验过的数据
# 保存
book = Book.objects.create(**validated_data)
return book
def update(self, instance, validated_data):
instance.name = validated_data.get('name')
instance.price = validated_data.get('price')
instance.save() # instance是个对象,对象可以一直点对象的方法
return instance
#局部钩子
def validate_name(self,name):
# 校验name
if name.startswith('2b'):
# 校验不通过主动抛异常
raise ValidationError('用户名不能2b开头')
pass
else:
return name
# 全局钩子
def validate(self, attrs):
"""
attrs:校验过的数据
"""
if attrs.get('price') == '0':
raise ValidationError('价钱不能为0')
else:
return attrs
总结
序列化类几个参数的用处
1. instance 传单个对象或queryset对象
"当我们传单个对象的时候不需要添加额外的参数只需要instance参数"
2. many 传 True 默认None
"当我们传一个queryset对象过去时,需要给many传参True"
3.data 传 需要检验的数据 如request.data携带的
4.validated_data 序列化类中校验过的数据
5.全局钩子和局部狗子在序列化类里是 用 validate 与validate_字段名代表
"其中需要什么参数传什么参数,全局钩子的attrs 就是校验过的参数可以拿出数据"
标签:ser,校验,instance,使用,import,序列化,data,drf
From: https://www.cnblogs.com/LiaJi/p/17084115.html