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

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')

我想访问嵌套序列化程序中的上下文,我该怎么做?据我所知,上下文并没有传递给子元素.

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

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

它适用于常规序列化程序,但在将嵌套子项传递给get_fields()时,上下文以及请求和用户不可用.当序列化程序嵌套时,如何访问上下文?

推荐答案

好的,我找到了一个有效的解决方案.我用SerializerMethodField替换了父类中的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):
        """
            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

这似乎很好,当我在Child.c_nameParent.child上撤销读取权限时,序列化程序中会丢弃子字段

Python-3.x相关问答推荐

按一列分组,如果日期列相同,则在数字列中填写缺少的值

如何在当前测试中使用fixture 转换后的数据进行参数化?

如何使用python将pdf文件的页面合并为单个垂直组合页面

不同的焦点顺序和堆叠顺序 tkinter

将水平堆叠的数据排列成垂直

通过匹配第一列的行值,逐个单元格地添加两个Pandas 数据框中的浮点数

有没有一种方法可以通过输入从 0 到 255 的 R、G 和 B 值来生成 RGB colored颜色 ,而无需使用 python 中的 matplotlib 模块?

判断是否存在大文件而不下载它

如何从脚本中提取 PDF 文档的标题以进行重命名?

两个字符串之间的正则表达式匹配?

django rest框架中的save()、create()和update()有什么区别?

使用 python 正则表达式匹配日期

无法在 Windows Python 3.5 上安装 Levenshtein 距离包

django - 值更改后自动更新日期

在 Python 3 中获取所有超类

定义 True,如果没有定义,会导致语法错误

如何将二进制(字符串)转换为浮点值?

如何在 QGraphicsView 中启用平移和zoom

什么是ANSI_X3.4-1968编码?

如何修复:cx_Oracle.DatabaseError:DPI-1047:找不到 64 位 Oracle 客户端库 - Python