Как получить атрибут связанного объекта, установленный в сериализаторе DRF? - PullRequest
0 голосов
/ 19 сентября 2019

Я пытаюсь вложить данные из одного атрибута связанного набора в один из моих сериализаторов DRF.

Пока что я могу сделать это только через промежуточный сериализатор, который кажется грязным.Я хотел бы сделать это напрямую.

На данный момент, это структура моего результата:

[
    {
        "id": 1,
        "name": "Pinot Noir",
        "wine_list": [
            {
                "id": 1,
                "wine": {
                    "id": 1,
                    "name": "Juan Gil"

                }
            }
        ]
    }
]

Дополнительный "список_ вин" избыточен и, конечно, не нужен.Я добился этого с помощью следующего кода.

Это мои модели.Я упростил их, включив только необходимую информацию.

class Varietal(models.Model):
    name = models.CharField(max_length=50)


class Wine(models.Model):
    name = models.CharField(max_length=100)


class WineVarietal(models.Model):
    wine = models.ForeignKey(Wine, on_delete=models.CASCADE)
    varietal = models.ForeignKey(Varietal, on_delete=models.CASCADE)

Это сериализаторы, с которыми я сейчас работаю.

class VarietalDetailWineSerializer(ModelSerializer):
    class Meta:
        model = Wine
        fields = ['id', 'name']


class VarietalDetailWineVarietalSerializer(ModelSerializer):
    wine = VarietalDetailWineSerializer()

    class Meta:
        model = WineVarietal
        fields = ['id', 'wine']


class VarietalDetailSerializer(ModelSerializer):
    wine_list = VarietalDetailWineVarietalSerializer(source='winevarietal_set', many=True)

    class Meta:
        model = Varietal
        fields = ['id', 'name', 'wine_list']

В идеале я бы получил что-то вроде этого:

[
    {
        "id": 1,
        "name": "Pinot Noir",
        "wine": [
            {
                "id": 1,
                "name": "Juan Gil"

            }
        ]
    }
]

С кодом, подобным следующему:

class VarietalDetailWineSerializer(ModelSerializer):
    class Meta:
        model = Wine
        fields = [
            'id',
            'name',
        ]


class VarietalDetailSerializer(ModelSerializer):
    wine = VarietalDetailWineSerializer(source='winevarietal_set.wine', many=True)

    class Meta:
        model = Varietal
        fields = [
            'id',
            'name',
            'wine',
        ]

Но это исходное значение недопустимо.

Peace.

1 Ответ

1 голос
/ 19 сентября 2019

Один из возможных способов добиться этого - использовать serializerMethodField.

class VarietalDetailSerializer(ModelSerializer):
    wine = SerializerMethodField()

    class Meta:
        model = Varietal
        fields = [
            'id',
            'name',
            'image',
            'description',
            'wine',
            'active'
        ]

    def get_wine(self, varietal):
        wine_varietals = varietal.winevarietal_set.all()

        wine = [wine_varietals.wine for wine_varietals in wine_varietals]

        return VarietalDetailWineSerializer(instance=wine, many=True).data

Нашей главной целью является добавление ответа many-to-many fields из пользовательского метода сериализатора.

...