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/Yedada/p/10602759.html
时间: 2024-10-11 04:30:29