【问题标题】:How to get specific fields from child serializers?如何从子序列化程序中获取特定字段?
【发布时间】:2019-08-06 13:50:01
【问题描述】:

说,有两种模式:

class Model1(models.Model):
    r = models.CharField(max_length=200)

class Model2(models.Model):
    p = models.CharField(max_length=200)
    m = models.ForeignKey(Model1,on_delete=models.CASCADE)

序列化器是:

class Model1Serializer(serializers.Serializer):
    class Meta:
        model = Model1
        fields = '__all__'

class Model2Serializer(serializers.Serializer):
    class Meta:
         model = Model2
         fields = '__all__'

给定的 Model1 序列化程序将输出返回为: { “身份证”:1, “r”:“r_value” }

模型 2 串行器输出为: { “身份证”:1, "p: "p_value", “米”:1 }

问题是我还想要 model2 序列化器输出中的 r 值。该怎么做?

【问题讨论】:

  • 请将正确答案标记为已接受。

标签: django django-rest-framework django-serializer serialization


【解决方案1】:

您需要使用正确的source 指定新字段 - 您可以在docs 中阅读更多信息。

选项 1:使用类 Serializer

class Model2Serializer(serializers.Serializer):
    id = serializers.IntegerField()
    p = serializers.CharField()
    r = serializers.CharField(source='m.r')

    class Meta:
         model = Model2
         fields = '__all__'

输出:{'p': u'pppp', 'r': u'rrrrr', 'id': 1}

选项 2:使用类 ModelSerializer

class Model2Serializer(serializers.ModelSerializer):
    r = serializers.CharField(source='m.r')

    class Meta:
         model = Model2
         fields = '__all__'

输出:{'p': u'pppp', 'r': u'rrrrr', 'm': 1L, u'id': 1}

选项 3:包含整个 Model1

class Model1Serializer(serializers.ModelSerializer):
    class Meta:
        model = Model1
        fields = '__all__'

class Model2Serializer(serializers.Serializer):
    m = Model1Serializer()

    class Meta:
        model = Model2
        fields = '__all__'

输出:{'m': OrderedDict([(u'id', 1), ('r', u'rrrrr')])}

【讨论】:

    【解决方案2】:

    1。如果你想要 r 作为 m 的属性

    定义特定关系字段的序列化器类

    
    class Model2Serializer(serializers.ModelSerializer):
        m = Model1Serializer()
        class Meta:
            model = Model2
            fields = '__all__'
    

    输出:

    
    [
        {
            "id": 1,
            "m": {
                "id": 1,
                "r": "RED"
            },
            "p": "Light RED"
        },
        {
            "id": 2,
            "m": {
                "id": 1,
                "r": "RED"
            },
            "p": "Dark RED"
        }
    ]
    

    2。如果你只想 r 使用 ReadOnlyField

    你可以使用 ReadOnlyField

    
    class Model2Serializer(serializers.ModelSerializer):
        r = serializers.ReadOnlyField(source='m.r')
    
        class Meta:
            model = Model2
            fields = '__all__'
    

    输出:

    [
        {
            "id": 1,
            "r": "RED",
            "p": "Light RED",
            "m": 1
        },
        {
            "id": 2,
            "r": "RED",
            "p": "Dark RED",
            "m": 1
        }
    ]
    

    3。如果你只想 r 使用 SerializerMethodField()

    你可以将 SerializerMethodField 设为只读

    
    class Model2Serializer(serializers.ModelSerializer):
        r = serializers.SerializerMethodField()
    
        class Meta:
            model = Model2
            fields = '__all__'
    
        def get_r(self, instance):
            return instance.m.r
    

    输出:

    [
        {
            "id": 1,
            "r": "RED",
            "p": "Light RED",
            "m": 1
        },
        {
            "id": 2,
            "r": "RED",
            "p": "Dark RED",
            "m": 1
        }
    ]
    

    【讨论】:

      【解决方案3】:

      试试这个

      class Model1Serializer(serializers.Serializer):
         class Meta:
            model = Model1
            fields = '__all__'
      
      class Model2Serializer(serializers.Serializer):
        r = Model1Serializer(many=True, source="model1_set")
        class Meta:
           model = Model2
           fields = '__all__'
      

      【讨论】:

        【解决方案4】:

        如果您已经有 Model1 的 Model1Serializer,DRF 会非常容易:

        class Model2Serializer(serializers.Serializer):
            m = Model1Serializer()
            class Meta:
                 model = Model2
                 fields = '__all__'
        

        应该是这样的。

        【讨论】:

          【解决方案5】:

          只需在您的序列化程序 Meta 中使用 depth=1。像这样:

          class Model2Serializer(serializers.Serializer):
              class Meta:
                   model = Model2
                   fields = '__all__'
                   depth = 1
          

          这将使该模型中确实存在的外键的级别为 1。 (顺便说一下,我不推荐给大模型,但它完全适合你的情况)

          【讨论】:

            猜你喜欢
            • 2018-05-22
            • 1970-01-01
            • 2020-11-15
            • 2021-07-03
            • 1970-01-01
            • 2018-02-20
            • 2015-01-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多