Сериализация 3 взаимосвязанных реляционных моделей Django
Я пытаюсь написать набор сериализаторов для своих моделей. Я хочу, чтобы сериализатор для колоды выплюнул карты, соответствующие ID колоды в модели CardToDeck, а затем получил карту, соответствующую card_id в модели Card
models.py
from django.db import models
# Create your models here.
class CardToDeck(models.Model):
deck_id = models.ForeignKey("Deck", related_name="card_to_deck", on_delete=models.CASCADE)
card_id = models.ForeignKey("Card", related_name="card_to_deck", on_delete=models.CASCADE)
class Card(models.Model):
id = models.AutoField(primary_key=True)
multiverseid = models.IntegerField(unique=True) # Used to fetch the card from the API
name = models.CharField(max_length=145)
class Deck(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=145)
serializers.py:
from .models import *
from rest_framework import serializers
class CardSerializer(serializers.ModelSerializer):
class Meta:
model = Card
fields = ('id', 'name')
class CardToDeckSerializer(serializers.ModelSerializer):
class Meta:
model = CardToDeck
fields = ('deck_id', 'card_id')
# Serializer for Deck that grabs the nested model references
class DeckSerializer(serializers.ModelSerializer):
cards = serializers.PrimaryKeyRelatedField(queryset=CardToDeck.objects.all(), many=True)
class Meta:
model = Deck
depth = 2
fields = ('name', 'cards')
Что бы я хотел, чтобы JSON выглядел следующим образом:
{
"name": "deckNameGoHere",
"cards": [{"id":1, "name":"cardNameGoHere", "quantity":3},{"id":2, "name":"cardNameGoHere", "quantity":2}]
}
Я только что потратил последние 4 часа, пытаясь разобраться в этом, и чувствую себя довольно тупым, любая помощь будет оценена по достоинству. Я заглянул в доки, но не смог найти нужных мне ресурсов.
Предполагая, что quantity
находится в CardToDeck
, вы можете сделать что-то вроде этого:
class CardToDeckSerializer(serializers.ModelSerializer):
id = serializers.CharField(source='card_id.id')
name = serializers.CharField(source='card_id.name')
class Meta:
model = CardToDeck
fields = ('id', 'name', 'quantity')
class DeckSerializer(serializers.ModelSerializer):
cards = CardToDeckSerializer(source='card_to_deck' many=True)
class Meta:
model = Deck
fields = ('name', 'cards')
Согласно документам DRF:
PrimaryKeyRelatedField может использоваться для представления цели отношения отношения используя его первичный ключ.
Вы можете использовать CardToDeckSerializer как поле DeckSerializer без PrimeryKeyRelated и как объект сериализатора, если вы хотите прочитать данные и вернуть их обратно:
from .models import *
from rest_framework import serializers
class CardSerializer(serializers.ModelSerializer):
class Meta:
model = Card
fields = ('id', 'name')
class CardToDeckSerializer(serializers.ModelSerializer):
class Meta:
model = CardToDeck
fields = ('deck_id', 'card_id')
# Serializer for Deck that grabs the nested model references
class DeckSerializer(serializers.ModelSerializer):
# if not intended to use bulk action it's better to keep the "many" fields as read only
cards = CardToDeckSerializer(many=True, read_only=True)
class Meta:
model = Deck
depth = 2
fields = ('name', 'cards')
Если вы хотите показать список связанных ссылок, вы можете использовать следующее:
HyperlinkedRelatedField
Я настоятельно рекомендую прочитать документ DRF о вложенных сериализаторах