13. 模型反序列化
在客户端发送POST
请求至后台时, 需要将其发送的数据转化为python对象, 此时便需要进行反序列化
反序列化的简单实现
基于REST的规范, 获取资源和创建资源应该分别对应同一个URL的GET
和POST
方法.
所以我们可以直接修改products/
路由对应的视图:
1
2
3
4
5
6
7
8
9
10
11
12
@api_view(['GET', 'POST'])
def product_list(request):
if request.method == 'GET':
queryset = Product.objects.all()
serializer = ProductSerializer(queryset, many=True,
context={'request': request})
return Response(serializer.data)
if request.method == 'POST':
serializer = ProductSerializer(data=request.data)
return Response("ok")
当视图方法设置为GET
, POST
时, Django REST framework会自动在接口页面创建一个表单, 以方便我们直接对接口进行测试.
数据校验
在视图方法中通过序列化对象进行数据校验, 只需要调用is_valid()
方法即可. 数据会自动根据数据模型的字段和验证器定义进行校验.
1
2
3
4
5
6
7
if request.method == 'POST':
serializer = ProductSerializer(data=request.data)
if serializer.is_valid():
print(serializer.validated_data)
return Response("ok")
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
此时, 如果想接口发送一个空对象, 则会得到如下返回信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# HTTP 400 Bad Request
# Allow: OPTIONS, POST, GET
# Content-Type: application/json
# Vary: Accept
{
"title": [
"This field is required."
],
"price": [
"This field is required."
],
"collection": [
"This field is required."
]
}
REST framework提供了一个更为简单的实现方式
通过给
is_valid()
方法添加关键字参数raise_exception=True
便可以得到完全相同的结果
1 2 3 4 5 if request.method == 'POST': serializer = ProductSerializer(data=request.data) serializer.is_valid(raise_exception=True) print(serializer.validated_data) return Response("ok")
前端数据验证
对于POST
数据不仅仅要进行数据类型, 非空, 查重等数据库验证, 有些时候也会需要进行一些数据有效性的验证. 比如创建用户操作时, 密码和确认密码是否相同一类.
此时可以直接在序列化对象中直接进行额外验证的编写, 在调用is_valid()
方法时便会在一同进行自定义验证.
在ProductSerializer
中添加如下代码:
1
2
3
4
5
def validate(self, attrs):
if attrs['unit_price'] > 100:
raise serializers.ValidationError("太贵了没人买")
return attrs
虽然在序列化对象时定义了字段命为
price
, 但这里的字段名称是unit_price
.因为验证是在数据反序列化之后才会进行的, 所以
attrs
对象中的键都是Product
模型类所定义的字段名.
本文由作者按照 CC BY 4.0 进行授权