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