# Serializer(instance=None, data=empty, **kwarg)
    用于序列化时,将模型类对象传入instance参数
    用于反序列化时,将要被反序列化的数据传入data参数
1. 创建模型类
# models.py创建模型类
from django.db import models
# Create your models here.
from django.db.models import Model
class TuShu(Model):
    # 主键自增,verbose_name字段描述
    tid = models.AutoField(primary_key=True, verbose_name="图书id")
    # 图书名称
    name = models.CharField(max_length=20, verbose_name="图书名称")
    # 上市日期 null=True允许为空
    riqi = models.DateField(null=True, verbose_name="上架日期")
    # 数量 default=0默认值
    count = models.IntegerField(default=0, verbose_name="数量")
    # 是否删除
    is_delete = models.BooleanField(default=False, verbose_name="是否删除")
    class Meta:
        # 数据表名字
        db_table = "tushu"  # 指定表名 默认自动生成表名
        verbose_name = "图书"  # #将会显示在admin站点中
    def __str__(self):
        return self.name  # admin站点中 每行数据展示的名称
class RenWu(Model):
    rid = models.AutoField(primary_key=True, verbose_name="任务编号")
    name = models.CharField(max_length=20, verbose_name="姓名")
    # 性别
    sex_choices = (
        (1, "男"),
        (0, "女")
    )
    sex = models.SmallIntegerField(verbose_name="性别", choices=sex_choices)
    desp = models.CharField(max_length=200, verbose_name="人物描述", null=True)
    is_delete = models.BooleanField(default=False, verbose_name="删除")
    # 外键 on_delete:主表删除的时候,相关数据怎么处理
    rt = models.ForeignKey(to=TuShu, to_field="tid", on_delete=models.CASCADE)
    class Meta:
        db_table = "renwu"
        verbose_name = "人物"
    def __str__(self):
        return self.name
'''
python manage.py makemigrations
python manage.py migrate
'''
2. 创建Serializer序列化类
# 1. 子应用中  为已经创建好的模型类在serializer.py中创建序列化类
from rest_framework import serializers
from rest_framework.serializers import Serializer
class TuShuSerializer(Serializer):
      # 描述模型类中的字段
      tid = serializers.IntegerField()
      name = serializers.CharField()
      riqi = serializers.DateField()
      id_delete = serializers.BooleanField()
# 2. 创建序列化对象 单条/结果集 返回数据 tss.data
class TuShuView(View):
    # 查询所有
    def get(self, request):
        # 所有图书 结果集
        qset = TuShu.objects.all()
        # 创建序列化对象 instance是需要序列化的数据,可以是一个数据对象,也可以是查询结果集
        # many=True 表示数据对象是查询结果集
        tss = TuShuSerializer(instance=qset, many=True)
        return JsonResponse(data=tss.data, safe=False) # 返回数据 tss.data
class TuShuView2(View):
    # 查询单个图书接口
    def get(self, request, tid):
        try:
            q = TuShu.objects.get(tid=tid)
        except Exception:
            return JsonResponse(data={}, status=404)
        tss = TuShuSerializer(instance=q) # 创建序列化对象
        return JsonResponse(data=tss.data, safe=False) # 返回数据
3. 嵌套序列化
# 先把没有关联的字段写出来; 再写关联字段
# 如果需要序列化的数据中包含有其他关联对象,则对关联对象数据的序列化需要指明
  # 1. PrimaryKeyRelatedField()序列化为关联对象的主键  -->序列化返回主键id
  # 2. StringRelatedField将会序列化为__str__返回字符串 -->序列化返回关联表的name
  # 3. TuShuSerializer()直接使用关联对象的序列化器对象  -->序列化返回整个关联数据
# 子应用中  在serializer.py中创建序列化类
 
class RenWuSerializer(Serializer):
    # label指定字段名称,read_only=True 该字段只用于序列化输出,不用于反序列化
    rid = serializers.IntegerField(label="人物id", read_only=True)
    name = serializers.CharField(label="人物名称", max_length=20)
    sex_choice = (
        (1, "男"),
        (2, "女")
    )
    # required = False 表示反序列化的时候,不必须输入,默认为True
    sex = serializers.ChoiceField(label="性别", choices=sex_choice, required=False)
    desp = serializers.CharField(label="人物描述", max_length=200, required=False, allow_null=True)
    is_delete = serializers.BooleanField(label="是否删除", default=False)
    # 关联字段
    # 1. PrimaryKeyRelatedField()序列化为关联对象的主键
    # {"rid": 1, "name": "xoxo", "sex": 1, "desp": "他曾经是个王者", "is_delete": true, "rt": 1},
    # rt = serializers.PrimaryKeyRelatedField(label="关联图书", read_only=True)
    # 2. StringRelatedField将会序列化为__str__返回字符串
    # {"rid": 1, "name": "xoxo", "sex": 1, "desp": "他曾经是个王者", "is_delete": true, "rt": "喜喜"}
    # rt = serializers.StringRelatedField(label="关联图书")
    # 3. 直接使用关联对象的序列化器对象
    #{"rid": 1, "name": "xoxo", "sex": 1, "desp": "他曾经是个王者", "is_delete": true,
    # "rt": {"tid": 1, "name": "喜喜", "riqi": "2022-01-03", "is_delete": true}}
    rt = TuShuSerializer()
# 视图函数
class RenWuView(View):
    def get(self, request):
        # 查询所有的人物
        qset = RenWu.objects.all()
        # 序列化
        rs = RenWuSerializer(instance=qset, many=True)
        return JsonResponse(data=rs.data, safe=False)
# 路由
  re_path(r"renwu/$", RenWuView.as_view(), name="renwu")
4. 多条数据嵌套序列化
# 注意: 类声明引用是 有顺序的
# 当我们一条数据 tushu 有多个关联对象 renwu 的时候,使用方式和上面大致一样
  '''
   1. 模型类名小写_set  作为序列化器中的字段名
   2. many = True
 '''
# tushu关联多个renwu
class TuShuSerializer(Serializer):
    # 描述模型类中的字段
    tid = serializers.IntegerField(label="图书id", read_only=True)
    name = serializers.CharField(label="图书名称", max_length=20)
    riqi = serializers.DateField(label="上市日期", required=False)
    count = serializers.IntegerField(label="图书数量", required=False)
    is_delete = serializers.BooleanField(label="是否删除", default=False)
    # {"tid": 1, "name": "喜喜", "riqi": "2022-01-03", "is_delete": true}
    # 三种方法
    # renwu_set = serializers.PrimaryKeyRelatedField(label="关联人物", many=True, read_only=True)
    # renwu_set = serializers.StringRelatedField(label="关联人物", many=True, read_only=True)
    # python代码从上到下执行,类卸载下面无法调用
    renwu_set = RenWuSerializer(read_only=True, many=True)
# 视图函数
class TuShuView(View):
    def get(self, request):
        # 查询所有
        qset = TuShu.objects.all()
        ts = TuShuSerializer(instance=qset, many=True)
        return JsonResponse(data=ts.data, safe=False)
# 路由
 re_path(r"tushu/$", TuShuView.as_view(), name="tushu"),