python - 覆盖 DRF 中序列化程序的数据属性

标签 python django django-rest-framework

我在个人项目中使用 django-rest-framework-mongoengine。我希望能够在列表请求中发送额外的数据。我为此编写了 2 个 mixin:

UserSearializerContextMixin:收集列表中存在的所有实例的用户 ID 列表。

class UserSerializerContextMixin(object):
    user_lookup_field = 'user_id'
    user_fields_required = ['id','full_name','image','level']
    _user_ids = []

    def update_context(self,user_id):
        if not self.context.get('user_ids'):
            self.context['user_ids'] = [user_id]
        else:
            self.context['user_ids'].append(user_id)

    def to_representation(self,instance):
        self.update_context(getattr(instance,self.user_lookup_field))
        return super(UserSerializerContextMixin,self).to_representation(instance)

UserSerializerDataMixin:使用在 to_representation 部分准备的上下文覆盖数据属性。

class UserSerializerDataMixin(object):

    @property   
    def data(self):

        ret = super(UserSerializerDataMixin, self).data
        // Override the data
        return ReturnDict(ret, serializer=self)

然后对于我的序列化器,我做这样的事情:

class DFSerializer(UserSerializerContextMixin,UserSerializerDataMixin,DocumentSerializer):
    //Fields and all

但不知何故,代码并没有进入覆盖的数据属性。我想从逻辑上讲,应该通过扩展 mixin 来覆盖数据属性。但这不会发生在这里。

可能是什么原因,如何解决?

最佳答案

这是一个非常古老的问题,但以防万一其他人偶然发现这个问题:

我来到这里是因为我不高兴 drf 需要为 TemplateHTMLRenderer 提供与其他渲染器不同的序列化器输出。因此,一种可能的解决方案涉及覆盖 data 属性以返回带有序列化程序和数据的字典,而不是包含相同序列化程序和数据的 ReturnList

无论如何,这里的问题是对于ViewSet中的list记录,不是你的序列化器直接实例化,而是一个ListSerializer相反,然后 ListSerializer 会为每个要序列化的特定记录调用您的序列化程序。

一个丑陋的补丁“修复”了这个问题可以像这样:

class YourViewSet(SomeBaseViewSet):

....

def get_serializer(self, *args, **kwargs):

    res = super().get_serializer(*args, **kwargs)

    class Patch(res.__class__):

        @property
        def data(self):
            request = self.context['request']
            if isinstance(request.accepted_renderer, TemplateHTMLRenderer):
                return dict(data=super().data,
                            serializer=self.child if isinstance(self, serializers.ListSerializer) else self)
            return super().data

    res.__class__ = Patch

    return res

截至撰写本文时,我仍在决定解决我的特定问题(需要不同序列化输出的 TemplateHTMLRenderer)的最佳方法是什么。接下来我正在测试覆盖渲染器,但上面的内容确实为我“解决”了我的问题,它也解释了为什么代码的行为不符合 OP 的预期。

关于python - 覆盖 DRF 中序列化程序的数据属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33910811/

相关文章:

python - Django 事务不起作用

html - Django POST 请求空表单 HTML 表单

python - 使用Flask和Flask-WTF中的路径和可选参数重定向到新页面不起作用

javascript - 在不单击任何按钮的情况下从 Web 使用 Flask 运行 python 脚本

python - 如何在python中替换列表中的字符

python - 如何加载文本文件并在单个图中绘制多列?

python - 如何运行克隆的 Django 项目?

python - 在Django中上传文件名

python - Django Rest框架非模型序列化器

python - 带有 PK 的 Django REST POST 到 HyperlinkedModelSerializer,如何将 PK 转换为 URL?