系列文章目录
第二章 序列化
前言
序列化:
drf中的序列化主要是用来将模型序列化成JSON格式的对象。但是除了序列化,他还具有表单验证功能,数据存储和更新功能。以下将进行讲解。
创建一个Serializer类:
这里我们以上一节的模型Merchant、GoodsCategory、Goods为例来讲解。首先我们创建一个Merchant的Serializer类。必须继承自Serializer及其子类。示例代码如下:
from rest_framework import serializers
from .models import Merchant,GoodsCategory,Goods
class MerchantSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(required=True,max_length=200)
logo = serializers.CharField(required=True,max_length=200)
notice = serializers.CharField(max_length=200,required=False)
up_send = serializers.DecimalField(max_digits=6,decimal_places=2,required=False)
lon = serializers.FloatField(required=True)
lat = serializers.FloatField(required=True,error_messages={"required":"必须传入lat!"})
def create(self, validated_data):
# create方法实现
return Merchant.objects.create(**validated_data)
def update(self,instance, validated_data):
# update方法实现
instance.name = validated_data.get('name',instance.name)
instance.logo = validated_data.get('logo',instance.logo)
instance.notice = validated_data.get('notice',instance.notice)
instance.up_send = validated_data.get('up_send',instance.up_send)
instance.lon = validated_data.get('lon',instance.lon)
instance.lat = validated_data.get('lat',instance.lat)
instance.save()
return instance
那么以后在视图函数中,可以使用他来对数据进行序列化,也可以对数据进行校验,然后存储数据。比如以下在视图函数中使用:
from .models import Merchant
from .serializers import MerchantSerializer
from django.http.response import JsonResponse
from django.views.decorators.http import require_http_methods
@require_http_methods(['GET','POST'])
def merchant(request):
if request.method == 'GET':
merchants = Merchant.objects.all()
serializer = MerchantSerializer(merchants,many=True)
return JsonResponse(serializer.data,safe=False)
else:
serializer = MerchantSerializer(data=request.POST)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data,status=200)
return JsonResponse(serializer.errors,status=400)
ModelSerializer:
之前我们在写序列化类的时候,几乎把模型中所有的字段都写了一遍,我们可以把模型中的字段移植过来即可。这时候就可以使用ModelSerializer类实现。示例代码如下
class MerchantSerializer(serializers.ModelSerializer):
class Meta:
model = Merchant
fields = "__all__"
Serializer的嵌套:
有时候在一个序列化中,我们可能需要其他模型的序列化。这时候就可以使用到序列化的嵌套。比如我们在GoodsCategory中想要获取Merchant以及这个分类下的商品Goods(只是为了演示,实际情况不一定要全部返回)。那么示例代码如下:
class GoodsSerializer(serializers.ModelSerializer):
class Meta:
model = Goods
fields = "__all__"
class MerchantSerializer(serializers.ModelSerializer):
class Meta:
model = Merchant
fields = "__all__"
class GoodsCategorySerializer(serializers.ModelSerializer):
merchant = MerchantSerializer(read_only=True,required=False)
goods_list = GoodsSerializer(many=True,required=False)
merchant_id = serializers.IntegerField(required=True,write_only=True)
class Meta:
model = GoodsCategory
fields = "__all__"
def validate_merchant_id(self,value):
if not Merchant.objects.filter(pk=value).exists():
raise serializers.ValidationError("商家不存在!")
return value
def create(self, validated_data):
merchant_id = validated_data.get('merchant_id')
merchant = Merchant.objects.get(pk=merchant_id)
category = GoodsCategory.objects.create(name=validated_data.get('name'), merchant=merchant)
return category
视图函数的写法还是跟之前一样:
@require_http_methods(['GET','POST'])
def goods_category(request):
if request.method == 'GET':
categories = GoodsCategory.objects.all()
serializer = GoodsCategorySerializer(categories,many=True)
return JsonResponse(serializer.data,safe=False)
else:
serializer = GoodsCategorySerializer(data=request.POST)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data)
else:
return JsonResponse(serializer.errors,status=400)
关于read_only和write_only:
- read_only=True:这个字段只只能读,只有在返回数据的时候会使用。
- write_only=True:这个字段只能被写,只有在新增数据或者更新数据的时候会用到。
验证:
验证用户上传上来的字段是否满足要求。可以通过以下三种方式来实现。
- 验证在Field中通过参数的形式进行指定。比如required等。
- 通过重写validate(self,attrs)方法进行验证。attrs中包含了所有字段。如果验证不通过,那么调用raise serializer.ValidationError(‘error’)即可。
- 重写validate_字段名(self,value)方法进行验证。这个是针对某个字段进行验证的。如果验证不通过,也可以抛出异常。
更多请参考:
- Serializer:https://www.django-rest-framework.org/api-guide/serializers/。
- Serializes Fields及其参数: https://www.django-rest-framework.org/api-guide/fields/。