如何从子序列化器获取特定字段?

时间:2019-03-15 13:07:11

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

说,有两种模型:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.example.android.time.MainActivity">


    <include layout="@layout/app_bar_main"
        android:layout_height="match_parent"
        android:layout_width="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:theme="@style/ThemeOverlay.AppCompat.navTheme"
        app:headerLayout="@layout/nav_drawer_header"
        app:menu="@menu/nav_drawer"/>
</android.support.v4.widget.DrawerLayout>

序列化器是:

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)

给定的Model1序列化器将输出返回为:     {         “ id”:1         “ r”:“ r_value”     }

,模型2序列化器输出为:     {         “ id”:1,         “ p:” p_value“,         “ m”:1     }

问题是我也希望在model2序列化器输出中使用r值。该怎么做?

5 个答案:

答案 0 :(得分:1)

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

选项1:具有类序列化器

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')])}

答案 1 :(得分:1)

尝试

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__'

答案 2 :(得分:0)

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

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

应该的。

答案 3 :(得分:0)

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。如果您只想使用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。如果只想使用SerializerMethodField()

您也可以SerializerMethodField和ist只读


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
    }
]

答案 4 :(得分:0)

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

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

此模型中确实存在的外键的级别为1。 (顺便说一句,我不建议将其用于大型机型。但这完全适合您的情况)