Moh*_*sen 15 python django-rest-framework
我想要一个完全只读ModelSerializer
,即只是列表/检索方法
最好的方法是什么?
mga*_*lgs 13
您真的想在视图(或Viewset)级别执行此操作,您可以使用ReadOnlyModelViewSet执行此操作.
(你在评论中提到了这一点,但我将其作为更好的可见性的答案).
D W*_*D W 11
如果您使用的是 a ModelSerializer
,则可以通过以下方式实现:
from rest_framework import serializers
class MyModelSerializer(serializers.ModelSerializer):
...
class Meta:
model = MyModel
fields = ("field_1", "field_2", etc)
read_only_fields = [f.name for f in MyModel._meta.get_fields()]
Run Code Online (Sandbox Code Playgroud)
该解决方案使用了_meta
django 模型的私有接口,但它相当稳定,并且被开发人员广泛使用。
在这里,我们只是生成相关模型中所有字段的列表,并将其应用于read_only_fields
来自的选项django-rest-framework
。
我更喜欢在序列化程序级别而不是视图级别执行此操作,因为它不会将您束缚于使用 mgalgs 建议的Viewset。
如果您想更进一步,您甚至可以将功能包装到一个 mixin 中,以添加到Meta
您的类的选项中。例如:
from rest_framework import serializers
from rest_framework.fields import Field
class ReadOnlyMixin(Field):
def __new__(cls, *args, **kwargs):
setattr(
cls.Meta,
"read_only_fields",
[f.name for f in cls.Meta.model._meta.get_fields()],
)
return super(ReadOnlyMixin, cls).__new__(cls, *args, **kwargs)
class MyModelSerializer(ReadOnlyMixin, serializers.ModelSerializer):
...
class Meta:
model = MyModel
fields = ("field_1", "field_2", etc)
Run Code Online (Sandbox Code Playgroud)
Luk*_*ent 11
如果您确实需要只读的序列化程序,那么覆盖init方法是最简洁和稳定的选项:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
setattr(self.Meta, 'read_only_fields', [*self.fields])
Run Code Online (Sandbox Code Playgroud)
与上述相比:
编辑更好的解决方案: 您可以更新 def get_fields 方法而不是 init 方法并创建一个抽象序列化程序:
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
Run Code Online (Sandbox Code Playgroud)
要使用它,只需从抽象序列化器继承:
def MySerializer(ReadOnlyModelSerializer):
class Meta:
model = MyModel
fields = '__all__'
Run Code Online (Sandbox Code Playgroud)
你唯一要做的就是创建一个像这样的序列化器.serializers.py
class YourdataSerializer(serializers.ModelSerializer):
class Meta:
model = Yourdata
# some data
fields = ('id', 'city', 'pincode', 'created')
read_only_fields = ('id', 'city', 'pincode', 'created')
Run Code Online (Sandbox Code Playgroud)
观看这样的事情
class YourdataList(APIView):
def get(self, request, format=None):
yourdata = YourdataList.objects.all()
serializer = YourdataSerializer(yourdata, many=True)
return Response(serializer.data)
Run Code Online (Sandbox Code Playgroud)
详细视图
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)
Run Code Online (Sandbox Code Playgroud)
这样做.