drf 序列化
serializer序列化组件
一、models准备
from django.db import models
# Create your models here.
class Book(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
publish_date = models.DateField(null=True)
xx = models.IntegerField(choices=((0, '文学类'), (1, '情感类')), default=1, null=True)
publish = models.ForeignKey(to='Publish', to_field='nid', on_delete=models.CASCADE, null=True)
authors = models.ManyToManyField(to='Author')
def __str__(self):
return self.name
def xxx(self):
return '123xxx'
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
age = models.IntegerField()
def __str__(self):
return self.name
class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
email = models.EmailField()
def __str__(self):
return self.name
def xx2(self):
return 'abc123'
二、序列化的两种方法:
2.1 Serializer
# app01serializer.py
from rest_framework import serializers
from app01 import models
class BookSerializer(serializers.Serializer):
name = serializers.CharField()
# 指定source=‘name’ ,表示序列化模型表中的name字段,重命名为name1
# name 和 source=‘name’ 指定的name不能重名
# name1 = serializers.CharField(source='name')
# write_only 序列化的时候,该字段不显示
# read_only 反序列化的时候,该字段不传
price = serializers.CharField()
publish = serializers.CharField(source='publish.name')
# source不但可以制定一个字段,也可以指定一个方法
# 下面的内容就是指定的方法
func_con = serializers.CharField(source='xxx')
# 跨表指定方法
func_con2 = serializers.CharField(source='publish.xx2')
book_type = serializers.CharField(source='get_xx_display', read_only=True)
# 序列化出版社的详情,指定SerializerMethodField之后,可以对应一个方法,
# 返回什么内容,publish_detail就是什么内容
publish_detail = serializers.SerializerMethodField(read_only=True)
# 对应方法固定写法: get_字段名字
def get_publish_detail(self, obj):
print(type(obj))
return {'name': obj.publish.name, 'city': obj.publish.city}
# 返回所有作者信息
authors = serializers.SerializerMethodField(read_only=True)
def get_authors(self, obj):
authorser = AuthorSerializer(obj.authors.all(), many=True)
return authorser.data
# views.py部分
from app01 import models
from app01.app01serializer import BookSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
class Book(APIView):
def get(self, request, *args, **kwargs):
response = {'code': 100, 'msg': '查询成功!'}
books = models.Book.objects.all()
booker = BookSerializer(instance=books, many=True)
print(type(booker.data))
response['data'] = booker.data
return Response(response)
def post(self, request):
# 实例化产生一个序列化类的对象,data是要反序列化的字典
booker = BookSerializer(data=request.data)
if booker.is_valid(raise_exception=True): # 校验booker数据格式
booker.create(booker.validated_data)
return Response()
2.2 ModelSerializer
# app01serializer.py
from rest_framework import serializers
from app01 import models
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = '__all__'
depth = 1 # 跨表 (与下方被注释部分目的一样)
# exclude=('name') # 与field不能同时用
"""
xx = serializers.CharField(source='get_xx_display')
authors = serializers.SerializerMethodField()
def get_authors(self, obj):
ret = AuthorSerializer(instance=obj.authors.all(), many=True)
return ret.data
"""
# views.py部分
def post(self,request):
#实例化产生一个序列化类的对象,data是要反序列化的字典
bookser=BookSerializer(data=request.data)
# bookser.data
if bookser.is_valid(raise_exception=True):
#清洗通过的数据
bookser.save()
else:
print(bookser.errors['name'][0])
return Response()