RESTFULL 02 序列化组件

RESTFULLL 序列化组件

一、Django自带序列化组件

​ 内置的serializers(把对象序列化成json字符串)(一般不用)

from django.core import serializers

def test(request):
    book_list = Book.objects.all()    
    ret = serializers.serialize("json", book_list)
    return HttpResponse(ret)

二、rest-framework序列化之Serializer

写一个类,继承Serializer
在类中写要序列化的字段
在View.py中使用
	book_ser=BookSerializer(book_list,many=True)
	book_ser.data   ----就是序列化后的数据
source的三种用法:
	1 指定字段
	2 指定方法
	3 深度查询(跨表)
SerializerMethodField,必须配合方法使用  get_字段名(self,obj),  obj是什么?当前要序列化的对象
SerializerMethodField对应的方法中还可以继续使用其他的序列化类

models

from django.db import models


# Create your models here.


class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.IntegerField()
    pub_date = models.DateField()
    publish = models.ForeignKey("Publish")
    authors = models.ManyToManyField("Author")

    def __str__(self):
        return self.title

    def test(self):
        return str(self.price) + self.title


class Publish(models.Model):
    name = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name


class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()

    def __str__(self):
        return self.name

views

from django.shortcuts import render
from django.http import JsonResponse
from app01 import models
from rest_framework.views import APIView
from rest_framework.response import Response
from app01.MySerializers import BookSerializer


# Create your views here.

class BooksView(APIView):
    # 不使用序列化组件
    # def get(self, request, *args, **kwargs):
    #     response = {'status': 100, 'msg': '成功'}
    #     book_list = models.Book.objects.all()
    #     book_ll = [{'id': book.pk, 'title': book.title, 'price': book.price} for book in book_list]  # 列表推导式
    #     response['data'] = book_ll
    #     # return JsonResponse(response, safe=False)
    #     # 需要在settings内注册rest_framework
    #     return Response(response)
    # 使用序列化组件
    def get(self, request, *args, **kwargs):
        response = {'status': 100, 'msg': '成功'}
        book_list = models.Book.objects.all()
        # 使用:实例化BookSerializer类,将要序列化的数据传如Queryset对象
        # 如果要序列化queryset对象,一定要加many=True
        book_ser = BookSerializer(book_list, many=True)
        response['data'] = book_ser.data
        return Response(response)

3 rest-framework序列化之ModelSerializer

写一个类继承ModelSerializer
在类内部写:
class Meta:
	model=models.Book
	fields='__all__'
	# exclude=['name','price']
	depth=1
重写属性

Myserializer

# 继承ModelSerializer,可以直接指定要序列化的表模型
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        # 指定要序列化book这个表
        model = models.Book
        # 指定要序列化的字段
        # fields=['nid','name']
        # 序列化所有字段
        fields = '__all__'

        # 选择要排除的字段(注意,不能跟fields连用)
        # exclude=['name','price']
        # 深度,官方建议最多写10,我个人建议最多写3
        # depth=1

    # publish=serializers.CharField(source='publish.name')
    # 显示出版社的详细信息
    publish = serializers.SerializerMethodField()

    def get_publish(self, obj):
        # print(type(obj))
        # print(obj)
        return {'id': obj.publish.pk, 'name': obj.publish.name}

    # 显示所有作者的信息
    authors = serializers.SerializerMethodField()

    def get_authors(self, obj):
        # 取到所有作者
        author_list = obj.authors.all()
        # author_ll=[ {'id':} for author in author_list]
        # 实例化一个作者的序列化类对象
        author_ser = AuthorSerializer(author_list, many=True)
		return author_ser.data		

4 查询单本书

​ -books/1
​ -序列化单条数据:book_ser=BookSerializer(instance=book,many=False)
​ -注意book:不是queryset对象,是book对象

# 获取单本图书的接口
class BookView(APIView):
    def get(self, request, pk, *args, **kwargs):
        response = {'status': 100, 'msg': '获取成功'}
        # 取到pk为传入的pk的书,book对象
        book = models.Book.objects.all().filter(pk=pk).first()
        # 要序列化单条,many=False
        book_ser = BookSerializer(instance=book, many=False)
        # book_ser=BookSerializer(book,many=False)
        response['data'] = book_ser.data

        return Response(response)

5 新增一本书

-/books/--发送post请求,携带json格式数据

views.py

# 获取单本图书的接口
class BookView(APIView):
    def get(self, request, pk, *args, **kwargs):
        response = {'status': 100, 'msg': '获取成功'}
        # 取到pk为传入的pk的书,book对象
        book = models.Book.objects.all().filter(pk=pk).first()
        # 要序列化单条,many=False
        book_ser = BookSerializer(instance=book, many=False)
        # book_ser=BookSerializer(book,many=False)
        response['data'] = book_ser.data

        return Response(response)

6 反序列化之局部,全局钩子(序列化的类一定是继承ModelSerializer的类

# 局部钩子
def validate_name(self,value):
	if value.startswith('sb'):
		#不能让你过
		raise ValidationError('书名不能以sb开头')
	else:
		return value
#全局钩子函数,对全局字段进行校验
def validate(self,a):
	# print(a)
	name=a.get('name')
	price=a.get('price')
	if name != price:
		raise ValidationError('错了')
	else:
		return a
原文地址:https://www.cnblogs.com/prodigal/p/10602759.html