简体   繁体   English

覆盖DRF中串行器的数据属性

[英]Override data property of serializer in DRF

I am using django-rest-framework-mongoengine for a personal project. 我正在使用django-rest-framework-mongoengine进行个人项目。 I want to be able to send extra data in list requests. 我希望能够在列表请求中发送额外的数据。 I have written 2 mixins for that purpose: 我为此编写了2个mixins:

UserSearializerContextMixin: Collects the list of user ids for all the instances present in the list. 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: Override the data property using the context prepared in to_representation part. UserSerializerDataMixin:使用to_representation部分中准备的上下文覆盖data属性。

class UserSerializerDataMixin(object):

    @property   
    def data(self):

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

Then for my serializer I do something like this: 然后对于我的序列化程序,我做这样的事情:

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

But somehow the code just does not enter the overridden data property. 但不知何故,代码只是没有输入重写的数据属性。 I guess logically the data property should be overridden by extending the mixin. 我猜逻辑上应该通过扩展mixin来覆盖data属性。 But it does not happen here. 但这不会发生在这里。

What could possibly be the reason and how to resolve? 可能是什么原因以及如何解决?

This is a super old question, but just in case somebody else stumbles upon this: 这是一个非常古老的问题,但万一其他人偶然发现了这个问题:

I came here because I was unhappy how drf requires a different serializer output for TemplateHTMLRenderer than it does for the other renderers. 我来到这里是因为我不满意drf是否需要为TemplateHTMLRenderer提供不同于其他渲染器的序列化器输出。 So one of the possible solutions involved overriding data property to return a dict with serializer & data instead of ReturnList containing the same serializer & data. 因此,一种可能的解决方案涉及覆盖data属性以返回带有序列化器和数据的dict,而不是包含相同序列化器和数据的ReturnList

Anyway, the problem here is that for listing records in the ViewSet, it is not your serializer instanced directly, but a ListSerializer instead and that ListSerializer then invokes your serializer for each particular record to be serialized. 无论如何,这里的问题是,为了在ViewSet中列出记录,它不是直接实例化的序列化程序,而是ListSerializer,而ListSerializer则为每个要序列化的特定记录调用序列化程序。

An ugly patch "fixing" this problem could be made like so: 一个丑陋的补丁“修复”这个问题可以像这样:

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

As of time of this writing, I'm still deciding what the best approach for solving my particular problem (TemplateHTMLRenderer requiring different serialized output) is. 截至撰写本文时,我仍然在决定解决我的特定问题的最佳方法(TemplateHTMLRenderer需要不同的序列化输出)。 I'm testing overriding the renderer next, but the above does "solve" my issue for me and it also explains why code didn't behave to OP's expectations. 我正在测试覆盖渲染器的下一个,但上面的确为我“解决”了我的问题,这也解释了为什么代码不符合OP的预期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM