Django休息框架: using DynamicFieldsModelSerializer for excluding serializer fields

标签 django python-3.x django-rest-framework

我有一个在几个端点(generics.ListAPIView)中使用的序列化器,但在其中一个端点中我需要隐藏序列化器字段。我不想仅仅为了解决这种情况而编写新的序列化器。

从 DRF 3.0 开始,我们为序列化器提供了动态字段 ( https://www.django-rest-framework.org/api-guide/serializers/#dynamically-modifying-fields ),但我在完全理解如何使用它们时遇到了一些麻烦。

我创建了这个序列化器:

class TestSerializer(DynamicFieldsModelSerializer):
    user_req = UserSerializer(read_only=True)
    user_tar = UserSerializer(read_only=True)

    class Meta:
        model = TestAssoc
        fields = ("user_req", "user_tar")

这是我的端点:

class TestEndpointListAPIView(generics.ListAPIView):
    serializer_class = TestSerializer
    permission_classes = [IsAuthenticated]
    lookup_field = 'test_username'

    def get_queryset(self):
        return ...

现在我需要从输出中隐藏“user_tar”字段,根据文档,我应该使用以下内容实例化序列化器:

TestSerializer(fields=('user_req'))

但是我应该如何在 TestEndpointListAPIView 中执行此操作?我应该重写 get_serializer 吗?

感谢您的帮助

编辑:

我通过重写 get_serialized 函数找到了以下解决方案:

def get_serializer(self, *args, **kwargs):
    serializer_class = self.get_serializer_class()
    kwargs['context'] = self.get_serializer_context()
    kwargs['fields'] = ['user_req']
    return serializer_class(*args, **kwargs)

我想知道这是否是一个好的解决方案。谢谢!

最佳答案

按照 DRF docs 中的建议,将这段代码添加到序列化器类的 __init__ 方法中:

class TestSerializer(serializers.ModelSerializer):
    user_req = UserSerializer(read_only=True)
    user_tar = UserSerializer(read_only=True)

    class Meta:
        model = TestAssoc
        fields = ("user_req", "user_tar")


    def __init__(self, *args, **kwargs):
        # Don't pass the 'fields' arg up to the superclass
        fields = kwargs.pop('fields', None)

        # Instantiate the superclass normally
        super(TestSerializer, self).__init__(*args, **kwargs)

        if fields is not None:
            # Drop any fields that are not specified in the `fields` argument.
            allowed = set(fields)
            existing = set(self.fields)
            for field_name in existing - allowed:
                self.fields.pop(field_name)

因此,当您从views.py 调用序列化器时,请执行以下操作:

TestSerializer(queryset, fields=('user_req'))

或者你可以做的是定义一个类

class DynamicFieldsModelSerializer(serializers.ModelSerializer):

    def __init__(self, *args, **kwargs):
        # Don't pass the 'fields' arg up to the superclass
        fields = kwargs.pop('fields', None)

        super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

        if fields is not None:
            allowed = set(fields)
            existing = set(self.fields)
            for field_name in existing - allowed:
                self.fields.pop(field_name)

如果您已在其他文件中定义了该类,则现在导入该类,然后使用

继承它
class TestSerializer(DynamicFieldsModelSerializer):

这样:

class TestSerializer(DynamicFieldsModelSerializer):
    user_req = UserSerializer(read_only=True)
    user_tar = UserSerializer(read_only=True)

    class Meta:
        model = TestAssoc
        fields = ("user_req", "user_tar")

现在你可以做

TestSerializer(queryset, fields=('user_req'))

更新
意见中。以ListAPIView为例

class DemoView(ListAPIView):
    queryset = TestAssoc.objects.all()

    def get(self, request):
        try:
            queryset = self.get_queryset()

            data = TestSerializer(queryset, fields=('user_req')).data

            return Response( {"data" : data } ,status=status.HTTP_200_OK)
        except Exception as error:
            return Response( { "error" : str(error) } , status=status.HTTP_500_INTERNAL_SERVER_ERROR)

关于Django休息框架: using DynamicFieldsModelSerializer for excluding serializer fields,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54893891/

相关文章:

python - Keyboard.record() 追加到列表

python - 如何在 django 中获取一周内每小时的平均值?

django - Django select_related链接的外键

python - 如何在 django orm 中使用过滤器值作为变量

django - SSL 证书未正确安装在 nginx 网络服务器上(Django 网络应用程序)

python-3.x - 如何从 Dataflow 批量(有效)发布到 Pub/Sub?

python - 如何遍历 df 的每一行/列以查看是否存在 0 或 ' '?

django - 在 Django 管理员中,如何将博客文章设置为仅在它不是草稿时进行验证?

Django Rest Framework Serializer charfield 在提供源时不会更新

Django REST 框架序列化程序 : Display the latest object of a reverse relationship