Search code examples
pythondjangodjango-modelsdjango-rest-frameworkforeign-keys

Django rest: accessing all related objects using ForeignKey


I'm stuck and I don't know what's wrong... to me it's identical to the "Nested relationships" example in the DRF API guide but something is not right...

MODEL

class PlayerSquadra(models.Model):
    
    player = models.ForeignKey(
       'app_player.Player',
       on_delete=models.CASCADE,
       verbose_name=_('giocatore'),
       related_name='player_squadraplayer',
    )

    squadra = models.ForeignKey(
        'app_stagione.Squadra',
        on_delete=models.CASCADE,
        verbose_name=_('squadra'),
        related_name='squadra_squadraplayer'
    )

    def __str__(self):
        return '%s' % (self.player)

URL

router.register(r'squadraJSON/(?P<squadra>.*)', views.SquadraViewSet)

VIEW

class SquadraViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Squadra.objects.all()
    serializer_class = SquadraSerializer

    def get_queryset(self):
        laSquadra = self.kwargs['squadra']
        queryset = Squadra.objects.filter(id=int(laSquadra))
        return queryset

SERIALIZER

class PlayerSquadraSerializer(serializers.ModelSerializer):
    class Meta:
        model = PlayerSquadra
        fields = '__all__'

class SquadraSerializer(serializers.ModelSerializer):
    playersquadra = PlayerSquadraSerializer(many=True, read_only=True)

    class Meta:
        model = Squadra
        fields = ['nomeSquadra','id','playersquadra']

What I get when I call http://192.168.0.102:8000/squadraJSON/26/ is:

GET /squadraJSON/26/
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "nomeSquadra": "prova2",
        "id": 26
    }
]

And no errors... While I expect something like this:

GET /squadraJSON/26/
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "nomeSquadra": "prova2",
        "id": 26
        "playersquadra": [
            {'id': 1, 'firstName': 'Michael', 'lastName': 'Jordan',...},
            {'id': 2, 'firstName': 'Larry', 'lastName': 'Bird',...},
            ...
        ],
    }
]

Could you give me some hint why I'm not getting all the players belonging to Squadra with id=26? Thanks for helping


Solution

  • You have to use the related_name to access all the related PlayerSquadra, which is squadra_squadraplayer, so:

    class SquadraSerializer(serializers.ModelSerializer):
        playersquadra = PlayerSquadraSerializer(
            many=True, read_only=True, source='squadra_squadraplayer',
        )
    
        class Meta:
            model = Squadra
            fields = ['nomeSquadra','id','playersquadra']
    

    or:

    class SquadraSerializer(serializers.ModelSerializer):
        # This will change the name of the key to squadra_squadraplayer
        squadra_squadraplayer = PlayerSquadraSerializer(many=True, read_only=True)
    
        class Meta:
            model = Squadra
            fields = ['nomeSquadra','id','squadra_squadraplayer']
    

    or even:

    class SquadraSerializer(serializers.ModelSerializer):
        playersquadra = serializers.SerializerMethodField()
    
        class Meta:
            model = Squadra
            fields = ['nomeSquadra','id','playersquadra']
        
        def get_playersquadra(self, obj):
            return PlayerSquadraSerializer(
                obj.squadra_squadraplayer, many=True, read_only=True,
            ).data