I want to have a total read only ModelSerializer, i.e. just list/retrieve methods
what is the best way to do it?
You really want to do this at the view (or Viewset) level, which you can do with a ReadOnlyModelViewSet.
(You mentioned this in your comment but I'm leaving it as an answer for better visibility).
For example (from the documentation):
from rest_framework import viewsets
class AccountViewSet(viewsets.ReadOnlyModelViewSet):
    """
    A simple ViewSet for viewing accounts.
    """
    queryset = Account.objects.all()
    serializer_class = AccountSerializer
                        If you do need a serializer to be read only, it's most concise and stable option to override the init method:
def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    setattr(self.Meta, 'read_only_fields', [*self.fields])
In comparison with the above:
EDIT better solution: You can update the def get_fields method instead of the init method and create an abstract serializer:
class ReadOnlyModelSerializer(serializers.ModelSerializer):
    def get_fields(self, *args, **kwargs):
        fields = super().get_fields(*args, **kwargs)
        for field in fields:
            fields[field].read_only = True
        return fields
To use it, just inherit from the abstract serializer:
def MySerializer(ReadOnlyModelSerializer):
   class Meta:
       model = MyModel
       fields = '__all__'
                        The only thing you have to do is create a serializer like this. serializers.py
class YourdataSerializer(serializers.ModelSerializer):
    class Meta:
        model = Yourdata
        # some data
        fields = ('id', 'city', 'pincode', 'created')
        read_only_fields = ('id', 'city', 'pincode', 'created')
Views something like this
class YourdataList(APIView):
    def get(self, request, format=None):
        yourdata = YourdataList.objects.all()
        serializer = YourdataSerializer(yourdata, many=True)
        return Response(serializer.data)
detail view
class YourdataDetail(APIView):
   def get_object(self, pk):
        try:
            return Yourdata.objects.get(pk=pk)
        except Yourdata.DoesNotExist:
            raise Http404
    def get(self, request, pk, format=None):
        snippet = self.get_object(pk)
        serializer = YourdataSerializer(snippet)
        return Response(serializer.data)
This will do it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With