Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I include a reverse relation that is not direct (goes through another resource) in django-tastypie?

I have 3 models. Game, player and piece. A player is attached to a game and a piece is attached to a player. The relations are simple foreign keys.

When retrieving the game, I wish to also retrieve all of the pieces from all of the players and include them in the result.

class GameResource(ModelResource):
    class Meta:
        queryset = Game.objects.all()
        resource_name = 'game'
        allowed_methods = ['get']

class PlayerResource(ModelResource):
    game = fields.ForeignKey(GameResource, 'game')
    class Meta:
        queryset = Player.objects.all()
        resource_name = 'player'
        allowed_methods = ['get']

class PieceResource(ModelResource):
    player = fields.ForeignKey(PlayerResource, 'player')
    class Meta:
        queryset = Piece.objects.all()
        resource_name = 'piece'
        allowed_methods = ['get']

I have no idea how this is done. I originally changed dehydrate so that it simply does the right query, calls django serialize, and puts it in a new variable in the bundle. This seems like a bodge to me. The serialize of the queryset was also serialized again by tastypie causing it to escape quotation characters (urgh).

like image 457
Adam Thomas Avatar asked Dec 15 '11 19:12

Adam Thomas


1 Answers

The solution is as follows:

class GameResource(ModelResource):
    players = fields.ToManyField('blokus.api.PlayerResource', 'player_set', full=True)
    class Meta:
        queryset = Game.objects.all()
        resource_name = 'game'
        allowed_methods = ['get']
        authorization = Authorization()


class PlayerResource(ModelResource):
    game = fields.ForeignKey(GameResource, 'game')
    pieces = fields.ToManyField('blokus.api.PieceResource', 'piece_set', full=True)

    class Meta:
        queryset = Player.objects.all()
        resource_name = 'player'
        allowed_methods = ['get']
        authorization = Authorization()


class PieceResource(ModelResource):
    player = fields.ForeignKey(PlayerResource, 'player')

    class Meta:
        queryset = Piece.objects.all()
        resource_name = 'piece'
        allowed_methods = ['get']
        authorization = Authorization()
like image 180
Adam Thomas Avatar answered Nov 07 '22 16:11

Adam Thomas