【DRF】序列化

系列文章目录

第二章 序列化



前言

序列化:
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:

  1. read_only=True:这个字段只只能读,只有在返回数据的时候会使用。
  2. write_only=True:这个字段只能被写,只有在新增数据或者更新数据的时候会用到。

验证:

验证用户上传上来的字段是否满足要求。可以通过以下三种方式来实现。

  1. 验证在Field中通过参数的形式进行指定。比如required等。
  2. 通过重写validate(self,attrs)方法进行验证。attrs中包含了所有字段。如果验证不通过,那么调用raise serializer.ValidationError(‘error’)即可。
  3. 重写validate_字段名(self,value)方法进行验证。这个是针对某个字段进行验证的。如果验证不通过,也可以抛出异常。

更多请参考:

  1. Serializer:https://www.django-rest-framework.org/api-guide/serializers/。
  2. Serializes Fields及其参数: https://www.django-rest-framework.org/api-guide/fields/。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值