Пример #1
0
    def find_serializer_fields(self, serializer_name):
        nodes = self.serializer_registry.nodes

        if serializer_name in self.memo_dict:
            return self.memo_dict[serializer_name]

        class_node = nodes[serializer_name]
        fields = Fields()
        init_node = None

        # Look at own class variables first, this trumps everything else
        for node in class_node.body:
            if self.is_class_var(node):
                # explicit class var trumps Meta
                fields.add(Resolver.drf_field_assignment(node), overwrite=True)
            elif self.is_meta(node):
                fields.extend(Resolver.drf_meta_fields(node))
            elif self.is_init_method(node):
                init_node = node

        # add fields from bases, in left to right order. The bases of the base
        # trumps the neighbour of the base if there's overlap.
        for base in class_node.bases:
            base = Resolver.resolve(base)

            if base == 'object':
                continue

            if base not in nodes:
                # TODO: ???
                continue

            base_class_vars = self.find_serializer_fields(base)
            fields.extend(base_class_vars)

        # Check for dynamic fields that were inherited from direct ancestors.
        # TODO: Find a better way to support inheritance
        parent_in_dynamic_fields = any(
            getattr(parent_class, 'attr', None) in self.dynamic_fields
            or getattr(parent_class, 'id', None) in self.dynamic_fields
            for parent_class in class_node.bases)

        # dynamic fields trump or augment existing fields
        if serializer_name in self.dynamic_fields or parent_in_dynamic_fields:
            if init_node:
                dynamic_fields = Resolver.init_method(init_node)
                for field_name, field in dynamic_fields.iteritems():
                    if field_name not in fields:
                        fields.add(field)
                        continue

                    previous_field = fields[field_name]
                    augmented_field = self.augment_field(previous_field, field)
                    fields.add(augmented_field, overwrite=True)

        self.memo_dict[serializer_name] = fields

        return fields
Пример #2
0
    def find_serializer_fields(self, serializer_name):
        nodes = self.serializer_registry.nodes

        if serializer_name in self.memo_dict:
            return self.memo_dict[serializer_name]

        class_node = nodes[serializer_name]
        fields = Fields()
        init_node = None

        # Look at own class variables first, this trumps everything else
        for node in class_node.body:
            if self.is_class_var(node):
                # explicit class var trumps Meta
                fields.add(Resolver.class_var_drf_field(node), overwrite=True)
            elif self.is_meta(node):
                fields.extend(Resolver.drf_meta_fields(node))
            elif self.is_init_method(node):
                init_node = node

        # add fields from bases, in left to right order. The bases of the base
        # trumps the neighbour of the base if there's overlap.
        for base in class_node.bases:
            base = Resolver.resolve(base)

            if base == 'object':
                continue

            if base not in nodes:
                # TODO: ???
                continue

            base_class_vars = self.find_serializer_fields(base)
            fields.extend(base_class_vars)

        # dynamic fields trump or augment existing fields
        if serializer_name in self.dynamic_fields:
            if not init_node:
                msg = ('Did not find __init__ in {} but view specifies dynamic'
                       ' fields.').format(serializer_name)
                raise Exception(msg)

            dynamic_fields = Resolver.init_method(node)
            for field in dynamic_fields:
                if field not in fields:
                    fields.add(field)
                    continue

                previous_field = fields[field['field_name']]
                augmented_field = self.augment_field(previous_field, field)
                fields.add(augmented_field, overwrite=True)

        self.memo_dict[serializer_name] = fields

        return fields