[Django]-Displaying the last object of nested relationship

3πŸ‘

βœ…

I feel that this should be solved on the query level, ideally with prefetch_related. But Django can’t slice Prefetch objects. Bummer. And Subquery is painstakingly slow.

The best solution I can think of, is creating a SerializerMethodField, which calls the TickerSerializer with a sliced dataset. The drawback is that DRF will fire an additional SQL query for each Currency object in the list.

from rest_framework.fields import SerializerMethodField

class CurrencySerializer(serializers.HyperlinkedModelSerializer):
    ticker = SerializerMethodField()

    def get_ticker(self, obj):
        return TickerSerializer(
            instance=obj.tickers.order_by('-created_at')[:1],
            many=True
        ).data

    class Meta:
        model = Currency
        fields = ('id', 'name','symbol', 'img', 'tickers', 'ticker')
πŸ‘€masterfloda

1πŸ‘

Think something like this would work, the problem with the current implementation is that the many=True would get all the related tickers and return those objects in a list, which is the correct behaviour, but since you want to only display the latest ticker for each currency you’ll need to serialize only the latest object.

class CurrencySerializer(serializers.HyperlinkedModelSerializer):
    tickers = serializers.SerializerMethodField()

    class Meta:
        model = Currency
        fields = ('id', 'name','symbol', 'img', 'tickers')

    def get_tickers(self, obj):
        data = {}
        try:
            latest_ticker = obj.tickers.latest('-created_at')
            data = TickerSerializer(instance=latest_ticker).data
        except Ticker.DoesNotExist:
            pass
        return data
πŸ‘€Pieter Hamman

Leave a comment