接收前端参数(反序列化) 且进行校验(含自定义校验) + 接口前段数据插入数据库
参考:
https://www.bilibili.com/video/BV1XR4y157rk?p=6&vd_source=caabcbd2a759a67e2a3de8acbaaf08ea
针对模型字段和属性见 https://blog.csdn.net/weixin_45827423/article/details/113405360
查询数据库的信息赋值实体类---序列化 见: https://www.cnblogs.com/kaibindirver/p/13264461.html
接收前端参数到实体类---反序列化
1、自定义校验失败提示的信息
2、用模型自己的1属性进行校验
#3、数据验证 ,抛出异常,代码不会往下执行
serializer.is_valid(raise_exception=True)
(可以把校验的那块BookSerializers独立出去)
from rest_framework import serializers
# 针对模型设计序列化器--(即前端要传什么字段给我们)
class BookSerializers(serializers.Serializer):
id=serializers.IntegerField(read_only=True) #在客户端提交数据【反序列化阶段不会要求有id字段】
name=serializers.CharField(required=True) #required=True=反序列化阶段必填
sex=serializers.BooleanField(default=True) #default=True,反序列化客户端没有填,默认为True
# 注意error_messages属性为触发错误提示的错误信息
age=serializers.IntegerField(max_value=100,min_value=0,error_messages=
{"max_value":"错误信息提示","min_value":"错误信息提示"}) #在反序列化必须 0<age<=100
# "max_value": "错误信息提示", "min_value": "错误信息提示"
description=serializers.CharField(allow_null=True,allow_blank=True) #允许客户端不填内容,或者传递一个""
import json
# Create your views here.
class BookView(APIView):
# 反序列化--采用字段选项来验证数据
def get(self, request):
#1、接收客户端提交的数据
# data=json.dumps(request.body)
# 模拟客户端请求body
data={
"name" :"amin",
"sex": 1,
"age":30,
"description":"这家伙很懒"
}
#2、实例化序列化器,获取序列化对象
serializer = BookSerializers(data=data)
#3、调用序列化器进行数据验证 不抛出异常,返回True or False
ret=serializer.is_valid()
print(f"{ret}")
# 获取验证后的结果
if ret:
print(serializer.validated_data)
else:
print(serializer.errors)
# 输出例子:{'age': [ErrorDetail(string='Ensure this value is greater than or equal to 0.', code='min_value')]}
#字段形式告诉你那个字段错误了
#指定错误字段的信息
print(serializer.errors["age"])
# 操作数据库
# 响应前端
return JsonResponse({})
反序列化的一些参数:
required 表明反序列化时,必须输入,默认是True
default 反序列化时使用的默认值
allow_null 反序列化,是否允许是None,默认是False
error_messages:错误信息展示
反序列化的一些检验参数:
max_length 最大长度
min_length 最小长度
allow_blank 是否允许为空
trim_whitespace 是否截断空白字符
max_value 最大值
min_value 最小值
read_only和write_only:
1、read_only: 序列化时需要该字段,反序列化时可以不需要该字段的数据
2、write_only: 是反序列化时需要该字段,序列化时不会有该字段的数据
序列化和反序列:
序列化就是从数据库中读取数据,返回给前端(查询数据时)。
反序列化就是将数据写入到数据库中,前端将数据传递给后端。(更新数据和增加数据)
简化判断错误校验你,只需要把 serializer.is_valid(raise_exception=True) 加上raise_exception=True,当校验错误即返回了错误信息给前端-----!!!!!工作中最常用!!!!!
# 反序列化--采用字段选项来验证数据抛出异常,工作中最常用
def get(self, request):
#1、接收客户端提交的数据
# data=json.dumps(request.body)
# 模拟客户端请求body
data={
"name" :"amin",
"sex": 1,
"age":130,
"description":"这家伙很懒"
}
#2、实例化序列化器,获取序列化对象
serializer = BookSerializers(data=data)
#3、调用序列化器进行数据验证 ,抛出异常,代码不会往下执行
serializer.is_valid(raise_exception=True)
# 校验正常,响应前端 {"name": "amin", "sex": 1, "age": 130, "description": "这家伙很懒"}
return JsonResponse(serializer.validated_data)
------------------------------------------------------------------自定义校验---------------------------------
把校验的1独立出来了,视图层还是调用BookView函数
1、单字段校验
2、多字段校验
3、指定某字段的校验函数
from rest_framework import serializers
# --------------------------#外部验证函数(注意这个方法在类外面)-------------------
# 在下面模型设计序列化器
# --对应字段使用属性validators指定这个函数做校验--注意要在模型设计序列化器前面
def check_classmate(data):
'''外部验证函数'''
if len(data) !=3:
raise serializers.ValidationError(detail="自定义校验不符合3", code="code不知做啥的")
# 验证成功以后,必须返回数据,否则该字段数据返回None
return data
# 针对模型设计序列化器
class BookSerializers(serializers.Serializer):
id=serializers.IntegerField(read_only=True) #在客户端提交数据【反序列化阶段不会要求有id字段】 可以不传
# validators指定外部校验函数,值是一个列表,列表里是是函数名,不能是字符串
name=serializers.CharField(required=True,validators=[check_classmate]) #required=True=反序列化阶段必填
sex=serializers.BooleanField(default=True) #default=True,反序列化客户端没有填,默认为True
# 注意error_messages属性为触发错误提示的错误信息
age=serializers.IntegerField(max_value=100,min_value=0,error_messages=
{"max_value":"错误信息提示","min_value":"错误信息提示"}) #在反序列化必须 0<age<=100
# "max_value": "错误信息提示", "min_value": "错误信息提示"
description=serializers.CharField(allow_null=True,allow_blank=True) #允许客户端不填内容,或者传递一个""
# -------------------validate--验证单个字段(单字段校验)------------------
#自定义验证字段,方法名的格式必须以 validate_<字段名>为名称,否则序列化器不识别!
def validate_name(self,data):
'''验证单个字段
validate开头的方法,会自动被is_valid调用 即是视图层使用的 serializer.is_valid()
'''
# 校验name字段
if data in ["python","django"]:
# 判断字段不符合抛出异常 {"name":["自定义校验不符合"]}
raise serializers.ValidationError(detail="自定义校验不符合",code="code不知做啥的")
# 验证成功以后,必须返回数据,否则该字段数据返回None
return data
#-------------------validate--验证所有客户端传过来的字段(多字段校验)-------------
# 校验代码的对象方法
def validate(self,attrs):
'''
验证来自客户端的所有数据
类似校验会员注册的密码和确认密码,就只能在validate方法中校验
validate是固定方法名
参数 attrs 是序列化器实例化的打他选项数据
'''
print(f"attrs={attrs}")
#307班只能有女生,且age<18
if attrs["sex"] ==1 and attrs["age"]:
raise serializers.ValidationError(detail="自定义校验不符合2", code="code不知做啥的")
return attrs
模型设计序列化校验 默认的是英文错误,修改项目的settings文件
LANGUAGE_CODE ='zh-hans'
返回的校验信息就会变成中文
-----------------插入数据库(拿到插入的id)-------
view.py
BookSerializers接受前端数据模型(上面的)
Publisher 是数据库数据模型modle层
from django.shortcuts import render
from rest_framework.views import APIView
from django.http import HttpResponse,JsonResponse
from OneApp.models import Publisher
from OneApp.serializers import BookSerializers
import json
# Create your views here.
class BookView(APIView):
# 反序列化--采用字段选项来验证数据抛出异常,工作中最常用
def get(self, request):
#1、接收客户端提交的数据
# data=json.dumps(request.body)
# 模拟客户端请求body
data={
"name" :"18",
# "sex": 1,
# "age":100,
# "description":""
}
#2、实例化序列化器,获取序列化对象
serializer = BookSerializers(data=data)
#3、调用序列化器进行数据验证 ,抛出异常,代码不会往下执行
serializer.is_valid(raise_exception=True)
#拿到校验成功的请求参数
data=serializer.validated_data # OrderedDict([('name', '18')])
print(json.dumps(data)) #序列化输出 {"name": "18"}
print(serializer.data) #序列化输出 {"name": "18"}
# 操作数据库插入
aa=Publisher.objects.create(**data)
BookSerializers(instance=aa).data #获取插入的信息 {'id': 26, 'name': '18'} ------这步可以拿到新增后的id
# 校验正常,响应前端
return JsonResponse(serializer.validated_data)
更便捷的写法
serializers.py
from rest_framework import serializers
from OneApp.models import Publisher
# 针对模型设计序列化器
class BookSerializers(serializers.Serializer):
id=serializers.IntegerField(read_only=True) #在客户端提交数据【反序列化阶段不会要求有id字段】 可以不传
# validators指定外部校验函数,值是一个列表,列表里是是函数名,不能是字符串
name=serializers.CharField(required=True) #required=True=反序列化阶段必填
# sex=serializers.BooleanField(default=True) #default=True,反序列化客户端没有填,默认为True
# 注意error_messages属性为触发错误提示的错误信息
# phone=serializers.IntegerField(read_only=True)
# description=serializers.CharField(allow_null=True,allow_blank=True) #允许客户端不填内容,或者传递一个""
# 模型操作方法
# 新增
def create(self,validated_data):
'''添加数据
添加数据操作,方法名固定为create,固定参数validated_data就是验证成功的结果,就自动实现从字段变为模型对象的过程
'''
publisher=Publisher.objects.create(**validated_data)
return publisher
# 更新
def update(self,instance,validated_data):
'''
更新数据
方法名固定为update
固定参数instance,实例化序列化器对象时,必须传入的模型对象
固定参数validated_data就是验证成功以后的结果
更新数据以后,就自动实现了从字段变成模型对象的过程
'''
instance.name=validated_data["name"]
instance.save()
return instance
view.py
from django.shortcuts import render
from rest_framework.views import APIView
from django.http import HttpResponse,JsonResponse
from OneApp.models import Publisher
from OneApp.serializers import BookSerializers
from django.core import serializers
import json
# Create your views here.
class BookView(APIView):
# 新增动作
def get2(self, request):
#1、接收客户端提交的数据
data={
"name" :"18",
# "sex": 1,
# "age":100,
# "description":""
}
#2、实例化序列化器,获取序列化对象
serializer = BookSerializers(data=data)
#3、调用序列化器进行数据验证 ,抛出异常,代码不会往下执行
serializer.is_valid(raise_exception=True)
# 4、获取验证以后的结果,操作数据库
serializer.save()
# 校验正常,响应前端
return JsonResponse(serializer.data,status=201) #{"id": 39, "name": "18"}
#更新动作
def get(self, request):
# 根据客户端传的数据主键id
try:
authorId=Publisher.objects.get(pk=2)
except Student.DoesNotExist:
return JsonResponse({"errors":"不存在数据"},status=400)
#1、接收客户端提交的数据
data={
"name" :"zhangsan5",
# "sex": 1,
# "age":100,
# "description":""
}
#2、修改操作中的实例化序列化对象
serializer = BookSerializers(instance=authorId,data=data)
#3、数据验证 ,抛出异常,代码不会往下执行
serializer.is_valid(raise_exception=True)
# 4、获取验证以后的结果,操作数据库
serializer.save() #可以传递一些模型中不存在,获不需要校验的数据 ----
# 校验正常,响应前端
return JsonResponse(serializer.data,status=201) #{"id": 39, "name": "18"}
不是很懂
查询序列化见 https://www.cnblogs.com/kaibindirver/p/17147733.html