【序列化常见字段】
其实就是嵌套,字典中对象嵌套字典,就用DictField,对象套列表用ListField
【序列化常见字段参数】
validators :该字段使用的验证器--》字段自己的校验[1 max_lenght 2 validators ],局部钩子,全局钩子
name=serializer.CharField(validators=[valida_name])
PS:翻译函数
# 翻译函数---》做好国际化
from django.utils.translation import gettext_lazy as _
def index(request):
res=_('Not a valid string')
print(res)
return HttpResponse(res)
【多表关联序列化和反序列化】
(source字段)
1.可以跨表查询
2.可以定制返回字段名,必须跟字段对应
3.所有字段都可以被转成CharField
PS:
source的用法是不改变序列化的情况下,定制字段的名字,也就是给在前端展示的字段名换了个别名,本质还是原来的字段名!!
source必须等于Book对象里面的字段名,不然就报错!!!而且起的别名不能和source等于的字段名起一样的,不然也报错!!
1 models.py 2 3 4 from django.db import models 5 6 7 # Create your models here. 8 9 class Book(models.Model): 10 name = models.CharField(max_length=50) 11 price = models.DecimalField(max_digits=5, decimal_places=2) 12 pub_date = models.DateField() 13 publish = models.ForeignKey('Publish', on_delete=models.CASCADE, null=True) 14 author = models.ManyToManyField('Author') 15 16 def __str__(self): 17 return self.name 23 class Publish(models.Model): 24 name = models.CharField(max_length=30) 25 email = models.EmailField() 26 city = models.CharField(max_length=30) 27 28 def __str__(self): 29 return self.name 30 31 32 class Author(models.Model): 33 name = models.CharField(max_length=30) 34 age = models.IntegerField() 35 36 def __str__(self): 37 return self.name
(定制返回字段)
ListField DictField
# 需求:后期想实现如下格式返回的数据
{name:书名,price:价格,publish:{name:出版社名,addr:地址},authors:[{},{}]}
方式一:
在表模型中定义方法,在序列化器中做映射
第二种方法:在模型类中写方法
通过SerializerMethodField,配合get_字段名使用
# 定制关联字段的值 的显示形式 -一对多的,显示字典 -多对多,显示列表套字典 ----------------------------------------- ----------------------------------------- 序列化类里面写的这些字段,作用就是,当序列化对象点is_valid()方法的时候, 先执行字段校验,再执行钩子函数,走完这些后,当序列化对象再点data时候, 又会通过对应的模型表对象去点字段名,然后组织成字典返回出去 如果模型表对象点的字段不在表里面,如果是定制返回格式一这种样子 就会自动去执行下面的函数,然后将返回结果作为值,字段名作为键,组织成字典返回出去 换句话说,写一个模型表里面不存在的字段名,并且用方式一这种形式, 那么函数对应的返回值是什么,返回给前端的字典里面,该不不存在的字段名键对应的值就是什么 ----------------------------------------- -----------------------------------------
对于不是序列化的表里面的字段名,我们可以改的,但是一改,下面对应的get_字段名的函数,函数名也要一起改!!!
第三种
通过子序列化器定制返回字段
ser.py # =========================通过子序列化器定制返回字段 # 把book表中的publish字段也返回, class PublishSerializer(serializers.Serializer): id = serializers.IntegerField() name = serializers.CharField() email = serializers.EmailField() city = serializers.CharField() class AuthorSerializer(serializers.Serializer): name = serializers.CharField() age = serializers.IntegerField() class BookSerializer(serializers.Serializer): name = serializers.CharField() price = serializers.DecimalField(max_digits=5, decimal_places=2) pub_date = serializers.DateField() # 子序列化器,也可以改字段 publish_detail = PublishSerializer(source='publish') # 序列化多条 author = AuthorSerializer(many=True)
多表关联反序列化保存
形式:
{name:书名,price:11,publish:2,authors:[1,2]}
新增反序列化保存
修改反序列化保存
(报错,用另外一种办法解决,instance仍然是obj)
views.py
class APP02BookDetailView(APIView):
def put(self, request, pk):
# 修改
obj = Book.objects.all().filter(pk=pk).first()
ser = BookSerializer(instance=obj, data=request.data)
if ser.is_valid():
ser.save() # 重写update方法
return Response('成功')
else:
return Response(ser.errors)
------------------------------------------------------------------------------------------------
# ser.py==================== 反序列化更新,instance 就传要修改的对象,保证修改完成
class BookSerializer(serializers.Serializer):
name = serializers.CharField()
price = serializers.DecimalField(max_digits=5, decimal_places=2)
pub_date = serializers.DateField(required=False, default=datetime.now)
# 反序列化字段----》多表关联,只能用来保存,字段可以随意命名,跟表字段没有关系,但是新增的时候要和这个字段名一致
publish = serializers.IntegerField(write_only=True) # 前端传入数字,自动跟出版社的id做对应
author = serializers.ListField(write_only=True)
def update(self, instance, validated_data):
# validated_data 校验过后的数据,
instance.name = validated_data.get('name')
instance.price = validated_data.get('price')
instance.publish_id = validated_data.get('publish')
# 先清空,再add author = validated_data.get('author')
instance.author.clear()
instance.author.add(*author)
instance.save() return instance
【ModelSerializer使用】