Как получить конкретные поля от дочерних сериализаторов? - PullRequest
0 голосов
/ 15 марта 2019

Скажем, есть две модели:

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 возвращает вывод в виде: {"id": 1, "r":" r_value "}

и вывод сериализатора модели 2: {" id ": 1," p: "p_value", "m": 1}

Дело в том, что ятакже хотите получить значение r в выводе сериализатора model2. Как это сделать?

Ответы [ 5 ]

1 голос
/ 15 марта 2019

Попробуйте это

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__'
1 голос
/ 15 марта 2019

Необходимо указать новое поле с правильным значением source - вы можете прочитать больше в документах .

Вариант 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')])}

0 голосов
/ 15 марта 2019

Просто используйте depth=1 в вашем сериализаторе Meta.Например:

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

Это перейдет на уровень 1 во внешние ключи, которые существуют в этой модели.( Кстати, Я не рекомендую его для больших моделей. Но он идеально подходит для вашей ситуации)

0 голосов
/ 15 марта 2019

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

output:

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

3.Если вы хотите просто использовать 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
    }
]
0 голосов
/ 15 марта 2019

DRF делает это довольно легко, если у вас уже есть Model1Serializer для Model1:

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

Так и должно быть.

...