1

I'm using Django Rest Framework with django-simple-history and currently I would like to return the history modifications in my Board rest API, currently it is doing well but I would like to hide some fields. This is the currently output:

enter image description here

But, I don't need id, history_id, etc.

my implementation is the same of alexander answer in this post. this is my currently serializers, where I put history on my Board model

class HistoricalRecordField(serializers.ListField):
    child = serializers.DictField()

    def to_representation(self, data):
        representation = super().to_representation(data.values())
        # i've tried to do it by deleting, but does't work well.
        del representation[0]['history_id']
        return representation


class BoardSerializer(serializers.ModelSerializer):
    history = HistoricalRecordField(read_only=True)

    class Meta:
        model = Board
        fields = '__all__'

But it does not seem the best way to do it.

If you have some hint about how to do it the correct way I would like to know. Thanks in advance!

2 Answers2

0

You can try this for history_id at least:

def to_representation(self, data):
        representation = super().to_representation(data.values())
        for hist in representation['history']:
            hist.pop('history_id')
        return representation
Yusuf Ertas
  • 261
  • 1
  • 5
0

I don't know django-simple-history, so they may be better solutions than mine.
However, you can do this with a more DRF-friendly approach by simply using a ModelSerializer instead of a ListSerializer:

class HistoricalRecordSerializer(serializers.ModelSerializer):

    class Meta:
        model = HistoricalRecords
        fields = ('name', 'description', 'share_with_company', [...]) # Only keep the fields you want to display here


class BoardSerializer(serializers.ModelSerializer):
    history = HistoricalRecordSerializer(read_only=True, many=True)

    class Meta:
        model = Board
        fields = ('name', 'description', 'history', [...]) # Only keep the fields you want to display here

If you want to only retrieve the latest update, you could use a SerializerMethodField (documentation here). Remember to declare it in Meta.fields instead of 'history' (or rename your SerializerMethodField "history" if you want to keep this name):

class HistoricalRecordSerializer(serializers.ModelSerializer):

    class Meta:
        model = HistoricalRecords
        fields = ('name', 'description', 'share_with_company', [...]) # Only keep the fields you want to display here


class BoardSerializer(serializers.ModelSerializer):
    latest_history = serializers.SerializerMethodField()

    def get_latest_history(self, instance):
        latest_history = instance.history.most_recent()  # Retrieve the record you want here
        return HistoricalRecordSerializer(latest_history).data

    class Meta:
        model = Board
        fields = ('name', 'description', 'latest_history', [...]) # Only keep the fields you want to display here

Keep in mind that I don't know much about this lib, so this should work but I cannot guarantee it's the best way to to it.

ThomasGth
  • 826
  • 7
  • 18
  • Your solution works very well, just one question before accept this answer: Using your approach, there is any way to show in the history field just the last update? history field show me all updates and it is what I need, but I'm just curious about the possibility to get just the last update (last object). – Leonardo Furtado Jan 05 '22 at 18:46