嵌套序列化程序中的上下文django休息框架 [英] context in nested serializers django rest framework

查看:152
本文介绍了嵌套序列化程序中的上下文django休息框架的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个嵌套的序列化程序:

  class ChildSerializer(ModelSerializer):
class Meta:
fields =('c_name',)
model = Child


class ParentSerializer(ModelSerializer):

child = ChildSerializer(many = read_only = True

class Meta:
model = Parent
fields =('p_name','child')
pre>

我想访问嵌套的序列化程序中的上下文,我该怎么做?据我所知,上下文不会传给孩子。



我希望能够为每个用户在字段上实现权限模型,因为我覆盖了ModelSerializer的get_fields()方法:

  def get_fields(self):
fields = super()。get_fields()
....
for f在字段中:
如果has_rights(self.context ['request']。user,f,read):
ret_val [f] = fields [f]
....
return ret_val

哪些适用于常规序列化程序,但是上下文,因此请求和用户当嵌套的子代被传递给get_fields()时不可用。串行器嵌套时,如何访问上下文?

解决方案

我找到了一个工作的解决方案。我用ParentizerMethodField替代了Parent类中的ChildSerializer赋值,该方法添加了上下文。然后将其传递给CustomModelSerializer中的get_fields方法:

  class ChildSerializer(CustomModelSerializer):
class Meta:
fields =('c_name',)
model = Child


class ParentSerializer(CustomModelSerializer):

child = serializers.SerializerMethodField 'get_child_serializer'

class Meta:
model = Parent
fields =('p_name','child')

def get_child_serializer(self, obj)
serializer_context = {'request':self.context.get('request')}
children = Child.objects.all()。filter(parent = obj)
serializer = ChildSerializer(children,many = True,context = serializer_context)
return serializer.data

在我的CustomModelSerializer中:

  class CustomModelSerializer(rest_serializer_classes.HyperlinkedModelSerializer):

def __init __(self,* args,** kwargs):

确保用户耦合到序列化程序(需要权限)

super ().__ init __(* args,** kwargs)
如果不是self.context:
self._context = getattr(self.Meta,'context',{})
try:
self.user = self.context ['request']。user
除了KeyError:
self.user = None


def get_fields(self) :
ret = OrderedDict()

如果不是self.user:
print(没有用户与对象关联)
return ret

fields = super()。get_fields()

#超级用户
如果self.user.is_superuser:
返回字段的Bypass权限

f在字段中:
if has_right(self.user,self.Meta.model .__ name __。lower(),f,read):
ret [f] = fields [f]

return ret

这似乎工作正常,孩子的字段在序列化程序中被丢弃我可以撤销 Child.c_name Parent.child


If i have a nested serializer:

class ChildSerializer(ModelSerializer):
    class Meta:
        fields = ('c_name', )
        model = Child


class ParentSerializer(ModelSerializer):

    child = ChildSerializer(many=True, read_only=True)

    class Meta:
        model = Parent
        fields = ('p_name', 'child')

And i want to access the context in the nested serializer, how can i do that? As far as i can tell, context isn't passed to the Child.

I want to be able to implement a permission model per user on fields, for that i overridden the get_fields() method of the ModelSerializer:

def get_fields(self):
    fields = super().get_fields()
    ....
    for f in fields:
        if has_rights(self.context['request'].user, f, "read"):
            ret_val[f] = fields[f]
    ....
    return ret_val

Which works for regular serializers, but the context, and thus the request and user are not available when the nested child is passed to get_fields(). How do i access the context when the serializer is nested?

解决方案

Ok i found a working solution. I replaced the ChildSerializer assignment in the Parent class with a SerializerMethodField which adds the context. This is then passed to the get_fields method in my CustomModelSerializer:

class ChildSerializer(CustomModelSerializer):
    class Meta:
        fields = ('c_name', )
        model = Child


class ParentSerializer(CustomModelSerializer):

    child = serializers.SerializerMethodField('get_child_serializer')

    class Meta:
        model = Parent
        fields = ('p_name', 'child')

    def get_child_serializer(self, obj):
        serializer_context = {'request': self.context.get('request') }
        children = Child.objects.all().filter(parent=obj)
        serializer = ChildSerializer(children, many=True, context=serializer_context)
        return serializer.data

and in my CustomModelSerializer:

class CustomModelSerializer(rest_serializer_classes.HyperlinkedModelSerializer):

    def __init__(self, *args, **kwargs):
        """
            Make sure a user is coupled to the serializer (needed for permissions)
        """
        super().__init__(*args, **kwargs)
        if not self.context:
            self._context = getattr(self.Meta, 'context', {})
        try:
            self.user = self.context['request'].user
        except KeyError:
            self.user = None


    def get_fields(self):
        ret = OrderedDict()

        if not self.user:
            print("No user associated with object")
            return ret

        fields = super().get_fields()

        # Bypass permission if superuser
        if self.user.is_superuser:
            return fields

        for f in fields:
            if has_right(self.user, self.Meta.model.__name__.lower(), f, "read"):
                ret[f] = fields[f]

        return ret

This seems to work fine, and fields of the child are discarded in the serializer when i either revoke read-rights on Child.c_name or on Parent.child

这篇关于嵌套序列化程序中的上下文django休息框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆