python 3.x - context in nested serializers django rest framework -
if have 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 want access context in nested serializer, how can that? far can tell, context isn't passed child.
i want able implement permission model per user on fields, overridden get_fields() method of modelserializer:
def get_fields(self): fields = super().get_fields() .... f in fields: if has_rights(self.context['request'].user, f, "read"): ret_val[f] = fields[f] .... return ret_val
which works regular serializers, context, , request , user not available when nested child passed get_fields(). how access context when serializer nested?
ok found working solution. replaced childserializer assignment in parent class serializermethodfield adds context. passed get_fields method in 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 custommodelserializer:
class custommodelserializer(rest_serializer_classes.hyperlinkedmodelserializer): def __init__(self, *args, **kwargs): """ make sure user coupled serializer (needed 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 object") return ret fields = super().get_fields() # bypass permission if superuser if self.user.is_superuser: return fields f in fields: if has_right(self.user, self.meta.model.__name__.lower(), f, "read"): ret[f] = fields[f] return ret
this seems work fine, , fields of child discarded in serializer when either revoke read-rights on child.c_name or on parent.child
Comments
Post a Comment