drf序列化组件

rest_framework序列化之Serializer

步骤:

1.自定义一个类,继承Serializer类;

2.在类中写要序列化的字段;

3.使用:在views.py文件中,book_ser=BookSerializer(book_list,many=True),book_ser.data就是序列化后的数据。当序列化的数据有多条(为QuerySet对象)时设置many=True,当序列化的数据只有一条(为obj对象)时设置many=False。

models部分:

from django.db import models

# Create your models here.


class Book(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish = models.ForeignKey(to='Publish', null=True, on_delete=models.SET_NULL, db_constraint=False)
    author = models.ManyToManyField(to='Author', db_constraint=False)


class Publish(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    address = models.CharField(max_length=16)


class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    author_detail = models.OneToOneField(to='AuthorDetail', null=True, on_delete=models.SET_NULL, db_constraint=False)


class AuthorDetail(models.Model):
    id = models.AutoField(primary_key=True)
    age = models.IntegerField()
    sex = models.SmallIntegerField(default=0)
    info = models.CharField(max_length=128)
View Code

views部分:

from rest_framework.views import APIView
from rest_framework.response import Response
from .models import *
from django.shortcuts import HttpResponse
from django.core import serializers


from rest_framework import serializers

class BookSerializers(serializers.Serializer):
    title=serializers.CharField(max_length=32)
    price=serializers.IntegerField()
    pub_date=serializers.DateField()
    publish=serializers.CharField(source="publish.name")
    #authors=serializers.CharField(source="authors.all")
    authors=serializers.SerializerMethodField()
    def get_authors(self,obj):
        temp=[]
        for author in obj.authors.all():
            temp.append(author.name)
        return temp
  #此处可以继续用author的Serializers,
  # def get_authors(self,obj):
    #     ret=obj.authors.all()
    #     ss=AuthorSerializer(ret,many=True)
    #     return ss.data

class BookViewSet(APIView):

    def get(self,request,*args,**kwargs):
        book_list=Book.objects.all()
        # 序列化方式1:
        # from django.forms.models import model_to_dict
        # import json
        # data=[]
        # for obj in book_list:
        #     data.append(model_to_dict(obj))
        # print(data)
        # return HttpResponse("ok")

        # 序列化方式2:
        # data=serializers.serialize("json",book_list)
        # return HttpResponse(data)

        # 序列化方式3:
        bs=BookSerializers(book_list,many=True)     #many=True代表有多条数据,如果只有一条数据,many=False
        return Response(bs.data)
     # 序列化方式4: 
      # ret=models.Book.objects.all().values('nid','title')
     # dd=list(ret)
        # return HttpResponse(json.dumps(dd))

注:

1.source指定的如果是字段,则会显示字段,如果是方法,则会执行方法,不用加括号(books=serializers.CharField(source='books.all'));

2.SerializerMethodField,必须配合方法使用  get_字段名(self,obj),obj是当前要序列化的对象;

3.SerializerMethodField对应的方法中还可以继续使用其他的序列化类。

rest_framework序列化之ModelSerializer

步骤:

1.自定义一个类继承ModelSerializer;

2.在类内部写:

class Meta:
    model=models.Book
     fields='__all__'
    # exclude=['name','price']
    depth=1
class BookSerializers(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        # fields = "__all__"
        fields=['nid','title','authors','publish']
        # exclude=('nid',)   #不能跟fields同时用
        # depth = 1    #深度控制,写 几 往里拿几层,层数越多,响应越慢,官方建议0--10之间,个人建议最多3层
    publish=serializers.SerializerMethodField()
    def get_publish(self,obj):
        return obj.publish.name
    authors=serializers.SerializerMethodField()
    def get_authors(self,obj):
        ret=obj.authors.all()
        ss=AuthorSerializer(ret,many=True)
        return ss.data

请求数据校验和保存:

   
class BooksView(APIView):
    def post(self, request):
        response = {'status': 200, 'msg': '修改成功'}
        try:
            obj_ser = self.BookSerializer(data=request.data)
            if obj_ser.is_valid():  # 校验
                obj_ser.save()  # 生成记录
                response['data'] = obj_ser.data
            else:
                response['msg'] = obj_ser.errors
        except Exception as e:
            response['msg'] = str(e)
        return Response(response)

校验字段局部和全局钩子函数:

class BookSerialzers(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'
        depth = 1
    
    #局部钩子函数,validate_字段名,value字段的值
    def validate_name(self, value):
        if re.match('^[0-9]+', value):
            raise ValidationError('书名不能以数字开头')
        return value

    #全局钩子函数,对全局字段进行校验
     def validate(self,objdict):
        name=objdict.get('name')
    price=objdict.get('price')
    if name != price:
        raise ValidationError('错了')
    else:
        return  objdict  

猜你喜欢

转载自www.cnblogs.com/wangke0917/p/10602781.html