今日内容
1 序列化高级用法之source(了解)
# 1 创建了5个表(图书管理的5个)
# 2 对booke进行序列化
# 总结:source的用法
-1 修改前端看到的字段key值---》source指定的必须是对象的属性
book_name = serializers.CharField(source='name')
-2 修改前端看到的value值,---》source指定的必须是对象的方法
表模型中写方法
def sb_name(self):
return self.name + '_sb'
序列化类中
book_name = serializers.CharField(source='sb_name')
-3 可以关联查询(得有关联关系)
publish_name = serializers.CharField(source='publish.name')
2 序列化高级用法之定制字段的两种方式(非常重要)
# 方式一:在序列化类中写
1 写一个字段,对应的字段类是:SerializerMethodField
2 必须对应一个 get_字段名的方法,方法必须接受一个obj,返回什么,这个字段对应的value就是什么
# 方式二:在表模型中写
1 在表模型中写一个方法(可以使用:property),方法有返回值(字典,字符串,列表)
2 在序列化类中,使用DictField,CharField,ListField
2.1 序列化类中写
### 2。1 定制字段方式1
class BookSerialzier(serializers.Serializer):
name = serializers.CharField()
price = serializers.CharField()
# 拿出出版社的id和名字和addr,放到一个字典中
# 方式一:SerializerMethodField来定制,如果写了这个,必须配合一个方法get_字段名,这个方法返回什么,这个字段的值就是什么
publish_detail = serializers.SerializerMethodField()
def get_publish_detail(self, book):
# print(obj) # 要序列化的book对象
return {'id': book.publish.pk, 'name': book.publish.name, 'addr': book.publish.addr}
# 练习:拿出所有作者的信息--》多条 [{name:,phone:},{}]
author_list = serializers.SerializerMethodField()
def get_author_list(self, book):
l = []
for author in book.authors.all():
l.append({'id': author.pk, 'name': author.name, 'phone': author.phone, 'age': author.author_detail.age})
return l
2.2 表模型中写
###### ###### ###### ###### ###### 序列化类###### ###### ###### ######
### 2.2 定制字段方式2
class BookSerialzier(serializers.Serializer):
name = serializers.CharField()
price = serializers.CharField()
# 1 序列化类中这样写
# 2 到表模型中写一个方法,方法名必须叫 publish_detail,这个方法返回什么,这个字段的value就是什么
publish_detail = serializers.DictField()
author_list=serializers.ListField()
###### ###### ###### ###### ###### 表模型###### ###### ###### ######
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32)
publish = models.ForeignKey(to='Publish', on_delete=models.SET_NULL, null=True)
authors = models.ManyToManyField(to='Author')
def sb_name(self):
return self.name + '_sb'
@property
def publish_detail(self):
return {'id': self.publish.pk, 'name': self.publish.name, 'addr': self.publish.addr}
def author_list(self):
l = []
for author in self.authors.all():
l.append({'id': author.pk, 'name': author.name, 'phone': author.phone, 'age': author.author_detail.age})
return l
3 多表关联反序列化保存
# 序列化和反序列化,用的同一个序列化类
-序列化的字段有:name,price , publish_detail,author_list
-反序列化字段:name,price ,publish,author
3.1 反序列化之保存
视图类
class BookView(APIView):
def post(self, request):
ser = BookSerialzier(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '成功'})
else:
return Response({'code': 100, 'msg': ser.errors})
序列化类
class BookSerialzier(serializers.Serializer):
# 即用来做序列化,又用来做反序列化
name = serializers.CharField(max_length=8)
price = serializers.CharField()
# 这俩,只用来做序列化
publish_detail = serializers.DictField(read_only=True)
author_list = serializers.ListField(read_only=True)
# 这俩,只用来做反序列化
publish_id = serializers.IntegerField(write_only=True)
authors = serializers.ListField(write_only=True)
def create(self, validated_data): # {name:西游记,price:88,publish:1,authors:[1,2]
authors = validated_data.pop('authors')
book = Book.objects.create(**validated_data)
book.authors.add(*authors)
book.save()
return book
3.2 反序列化之修改
视图类
class BookDetailView(APIView):
def put(self, request,pk):
book=Book.objects.get(pk=pk)
ser = BookSerialzier(data=request.data,instance=book)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '更新成功'})
else:
return Response({'code': 100, 'msg': ser.errors})
序列化类
class BookSerialzier(serializers.Serializer):
# 即用来做序列化,又用来做反序列化
name = serializers.CharField(max_length=8)
price = serializers.CharField()
# 这俩,只用来做序列化
publish_detail = serializers.DictField(read_only=True)
author_list = serializers.ListField(read_only=True)
# 这俩,只用来做反序列化
publish_id = serializers.IntegerField(write_only=True)
authors = serializers.ListField(write_only=True)
def update(self, instance, validated_data):
authors = validated_data.pop('authors')
for item in validated_data:
setattr(instance, item, validated_data[item])
instance.authors.set(authors)
instance.save()
return instance
4 反序列化字段校验其他
# 视图类中调用:ser.is_valid()---》触发数据的校验
-4层
-字段自己的:max_length,required。。。
-字段自己的:配合一个函数name = serializers.CharField(max_length=8,validators=[xxx])
-局部钩子
-全局钩子
5 ModelSerializer使用
# 之前写的序列化类,继承了Serializer,写字段,跟表模型没有必然联系
class XXSerialzier(Serializer)
id=serializer.CharField()
name=serializer.CharField()
XXSerialzier既能序列化Book,又能序列化Publish
# 现在学的ModelSerializer,表示跟表模型一一对应,用法跟之前基本类似
1 写序列化类,继承ModelSerializer
2 在序列化类中,再写一个类,必须叫
class Meta:
model=表模型
fields=[] # 要序列化的字段
3 可以重写字段,一定不要放在class Meta
-定制字段,跟之前讲的一样
4 自定制的字段,一定要在fields中注册一下
5 class Meta: 有个extra_kwargs,为某个字段定制字段参数
6 局部钩子,全局钩子,完全一致
7 大部分请情况下,不需要重写 create和update了
作业
# 1 book上课讲的也写一遍
#2 Publish的5个接口,ModelSerializer写
# 3 author的5个接口(写不出来没关系)(
-新增或修改author时,把author_detail的内容也新增进去
model层
from django.db import models
# Create your models here.
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32)
publish = models.ForeignKey(to='Publish', on_delete=models.SET_NULL, null=True)
def publish_detail(self):
return {'id': self.publish.id, 'name': self.publish.name, 'addr': self.publish.addr}
authors = models.ManyToManyField(to='Author')
def authors_detail(self):
l = []
for author in self.authors.all():
l.append({'name': author.name, 'age': author.age, 'email': author.auth_detail.email,
'phone': author.auth_detail.phone})
return l
# def author_detail(self):
# return {'id':self.authors,'name':self.authors.name}
class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.CharField(max_length=32)
auth_detail = models.OneToOneField(to='AuthorsDetail', on_delete=models.CASCADE)
class AuthorsDetail(models.Model):
email = models.CharField(max_length=32)
phone = models.BigIntegerField()
view层
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Book, Publish, Author
from app01.bookSerializer import BookSerializer, PublishSerializer, AuthorSerializer
class AuthView(APIView):
def get(self, request):
auth = Author.objects.all()
ser = AuthorSerializer(instance=auth, many=True)
return Response({'code': 100, 'msg': ser.data})
def post(self, request):
ser = AuthorSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 200, 'msg': '添加成功'})
else:
return Response({'code': 100, 'msg': ser.errors})
class AuthDetailView(APIView):
def get(self, request, pk):
author = Author.objects.get(pk=pk)
ser = AuthorSerializer(instance=author)
return Response({'code': 100, 'msg': ser.data})
def put(self, request, pk):
author = Author.objects.get(pk=pk)
ser = AuthorSerializer(instance=author, data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 200, 'msg': '修改成功'})
else:
return Response({'code': 100, 'msg': ser.errors})
def delete(self, request, pk):
Author.objects.filter(pk=pk).delete()
return Response({'code': 200, 'msg': '删除成功'})
serializer层
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ['name', 'age', 'email', 'phone', 'id', 'detail_email', 'detail_phone', 'auth_detail']
extra_kwargs = {
'auth_detail': {'read_only': True}
}
# auths_detail = serializers.DictField(read_only=True)
# 只读
email = serializers.CharField(source='auth_detail.email', read_only=True)
phone = serializers.IntegerField(source='auth_detail.phone', read_only=True)
# 只写
detail_email = serializers.CharField(write_only=True)
detail_phone = serializers.IntegerField(write_only=True)
def create(self, validated_data):
author_detail_obj = AuthorsDetail.objects.create(phone=validated_data.get('detail_phone'),
email=validated_data.get('detail_email'))
author_obj = Author.objects.create(name=validated_data.get('name'), age=validated_data.get('age'),
auth_detail_id=author_detail_obj.pk)
return author_obj
def update(self, instance, validated_data):
print(validated_data)
# print(instance.__dict__)
instance.name = validated_data['name']
instance.age = validated_data['age']
instance.save()
auth_detail = instance.auth_detail
auth_detail.email = validated_data['detail_email']
auth_detail.phone = validated_data['detail_phone']
auth_detail.save()
return instance
标签:modelserializer,name,author,self,detail,Day04,serializers,序列化
From: https://www.cnblogs.com/yedayangboke/p/17416176.html