Django Rest Framework只读模型序列化器

时间:2016-07-12 04:05:17

标签: python django-rest-framework

我想要一个完全只读-----END RSA PRIVATE KEY-----,即只列出/检索方法

最好的方法是什么?

6 个答案:

答案 0 :(得分:10)

您确实希望在视图(或视图集)级别执行此操作,您可以使用ReadOnlyModelViewSet执行此操作。

(您在评论中提到了这一点,但我将其留作了更好的知名度的答案)。

答案 1 :(得分:7)

你唯一要做的就是创建一个像这样的序列化器。 serializers.py

class YourdataSerializer(serializers.ModelSerializer):
    class Meta:
        model = Yourdata
        # some data
        fields = ('id', 'city', 'pincode', 'created')
        read_only_fields = ('id', 'city', 'pincode', 'created')

观看类似这样的内容

class YourdataList(APIView):
    def get(self, request, format=None):
        yourdata = YourdataList.objects.all()
        serializer = YourdataSerializer(yourdata, many=True)
        return Response(serializer.data)

详细视图

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)

这样就可以了。

答案 2 :(得分:2)

如果您使用的是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()]

此解决方案使用django模型的专用_meta接口,但它相当稳定,并且开发人员已相当广泛地使用它。

在这里,我们只是生成相关模型中所有字段的列表,并将其应用于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)

答案 3 :(得分:1)

好的亲爱的Mohsen,要使用BaseSerializer类实现只读序列化,我们只需要覆盖.to_representation()方法。让我们看一个使用简单Django模型的例子:

class HighScore(models.Model): 
 created = models.DateTimeField(auto_now_add=True) 
 player_name=models.CharField(max_length=10) 
 score = models.IntegerField()

创建只读序列化程序以将HighScore实例转换为原始数据类型非常简单。

class HighScoreSerializer(serializers.BaseSerializer):
 def to_representation(self, obj): 
  return { 'score': obj.score,  'player_name': obj.player_name }

答案 4 :(得分:1)

如果您确实需要一个序列化器为只读,则覆盖 init 方法的最简洁,最稳定的选择是:

def __init__(self, *args, **kwargs):
    super(MySerializer, self).__init__(*args, **kwargs)
    setattr(self.Meta, 'read_only_fields', [*self.fields])

与上述相比:

  • @mgalgs的解决方案是最好的,如果与所使用的序列化器无关的视图应该是只读的。
  • 如果只有几个非动态字段,
  • @thisisms解决方案是最好的
  • @D W的方法仅在没有使用'source'关键字的可写序列化字段时才有效。

答案 5 :(得分:0)

对此有两种解决方案?

from rest_framework.utils import model_meta

class CustomSerializer(serializers.ModelSerializer):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        model = getattr(self.Meta, 'model')
        declared_fields = copy.deepcopy(self._declared_fields)
        info = model_meta.get_field_info(model)
        field_names = self.get_field_names(declared_fields, info)
        _, hidden_fields = self.get_uniqueness_extra_kwargs(
        field_names, declared_fields, extra_kwargs)
        fields_names.extend(hidden_fields.keys())
        setattr(self.Meta, 'read_only_fields', list(field_names))

class CustomSerializer(serializers.ModelSerializer):

    def __init__(self, *args, **kwargs):
        super().__init__()
        setattr(self.Meta, 'read_only_fields', list(self.fields))