zoukankan      html  css  js  c++  java
  • 定义序列化器之关联属性(一对多、多对多)

    定义序列化器,通常是拿模型类的代码过来修改一下。但是如果遇到有关联属性的时候,应该怎么写呢?

    假设有两个模型类,一个是员工,一个是部门。部门与员工是一对多关系。那么在定义序列器的时候怎么写关联属性的语句呢?

    先把没有涉及关联属性的字段写成序列化器:

    from rest_framework import serializers
    
    
    class DepartmentSerializer(serializers.Serializer):
        """部门序列化器类"""
        id = serializers.IntegerField(read_only=True)
        name = serializers.CharField(max_length=20)
        create_date = serializers.DateField()class EmployeeSerializer(serializers.Serializer):
        """员工序列化器"""
    
        choices_gender = (
            (0, ''),
            (1, ''),
        )
    
        name = serializers.CharField(max_length=20)
        age = serializers.IntegerField()
        gender = serializers.ChoiceField(default=0, choices=choices_gender)
        salary = serializers.DecimalField(max_digits=8, decimal_places=2)
        comment = serializers.CharField(max_length=300)
        hire_date = serializers.DateField()
    • 一对多关系中,多的那方的序列化器关联属性的写法:

    如果我要对员工对象序列化时有这样的效果:

    # 第一种效果
    { "name": "赵小一",
        ..., "department": 1, # 第1种:PrimaryKeyRelatedField }

    # 第二种效果 { "name": "赵小一",
        ..., "department": "研发部", # 第2种:StringRelatedField }

    # 第三种效果 { "name": "赵小一",
        ..., "department": { # 第3种:DepartmentSerializer "id": 1, "name": "研发部", "create_date": "2018-1-1" } }

    员工序列化器的定义如下:

    class EmployeeSerializer(serializers.Serializer):
        """员工序列化器"""
    
        choices_gender = (
            (0, ''),
            (1, ''),
        )
    
        name = serializers.CharField(max_length=20)
        age = serializers.IntegerField()
        gender = serializers.ChoiceField(default=0, choices=choices_gender)
        salary = serializers.DecimalField(max_digits=8, decimal_places=2)
        comment = serializers.CharField(max_length=300)
        hire_date = serializers.DateField()
        # 定义序列化器时关联属性的设置
        # 1.1 返回关联属性的主键,设置属性为read_only=True表示修改时,即使传过来的员工信息有部门的id,也不做修改,保留原始的值!
        department = serializers.PrimaryKeyRelatedField(read_only=True)
        # 1.2 返回关联属性的主键,设置属性为查询集,表示修改时,当你要修改部门时,如果查询集有,可以修改,如果没有,不可以修改!
        department = serializers.PrimaryKeyRelatedField(queryset=Department.objects.all())
        # 2 返回关联属性的类的__str__方法的值。如果我们想要返回部门的名称,可以在model里面增加__str__方法返回部门名称
        department = serializers.StringRelatedField()
        # 3 返回关联属性的所有属性值时,可以这样写:
        department = DepartmentSerializer()
    • 一对多关系中,一的那方的序列化器关联属性的写法:(多对多关系的两边都可以这样写

    部门序列化器的定义如下:

    class DepartmentSerializer(serializers.Serializer):
        """部门序列化器类"""
        id = serializers.IntegerField(read_only=True)
        name = serializers.CharField(max_length=20)
        create_date = serializers.DateField()
        is_delete = serializers.BooleanField(default=False)
        # 返回关联属性的主键,因为有多个,所以必须加上many=True
        employee_set = serializers.PrimaryKeyRelatedField(read_only=True,many=True)
        # 返回关联属性的类的__str__方法的值。如果我们想要返回员工的名字,可以在model里面增加__str__方法返回员工的名字。
        employee_set = serializers.StringRelatedField(many=True)
        # 返回关联属性的所有属性值
        employee_set = EmpSerializer(many=True)

    注意:因为一的这方序列化时会出现多条关联属性,所以必须加上many=True。

     

    • 一个小小的坑

    如果在一个文件中,定义了员工和部门的序列化器,并且,两个序列化器都返回关联属性的所有属性值时:

    部门序列化器有这句语句:

    employee = EmployeeSerializer(many = True)

    员工序列化器有这句语句:

    department = DepartmentSerializer()

    此时会出现相互引用的情况,导致出错!

    解决办法:

    在部门序列化器前再加多一个员工序列化器,并且把department = DepartmentSerializer()删掉!

  • 相关阅读:
    每日一篇文献:Robotic pick-and-place of novel objects in clutter with multi-affordance grasping and cross-domain image matching
    每日一篇文献:Intuitive Bare-Hand Teleoperation of a Robotic Manipulator Using Virtual Reality and Leap Motion
    每日一篇文献:Virtual Kinesthetic Teaching for Bimanual Telemanipulation
    HEBI Robotic Arm VR Teleoperation
    「iQuotient Case」AR device teleoperated robotic arm
    VR and Digital Twin Based Teleoperation of Robotic Arm
    HEBI Robotic Arm VR Teleoperation
    Human Robot Interaction
    Immersive Teleoperation Project
    机器人演示学习
  • 原文地址:https://www.cnblogs.com/chichung/p/9937176.html
Copyright © 2011-2022 走看看