【序列化常见字段】

 

 其实就是嵌套,字典中对象嵌套字典,就用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使用】

 

 

 



posted on 2024-04-13 21:17  认真的六六  阅读(5)  评论(0编辑  收藏  举报