Created
August 11, 2016 18:28
-
-
Save caseyrollins/4c43f8465906db9e00a776f881ebf9b5 to your computer and use it in GitHub Desktop.
VOL Node Relationships -- Disallow orphaned children nodes from being associated with VOL (get_eligible_nodes)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ViewOnlyLinkNodesSerializer(ser.Serializer): | |
data = ser.ListField(child=VOLNode()) | |
links = LinksField({ | |
'self': 'get_self_url', | |
}) | |
def get_self_url(self, obj): | |
return absolute_reverse( | |
'view-only-links:view-only-link-nodes', | |
kwargs={ | |
'link_id': obj['self']._id | |
} | |
) | |
def make_instance_obj(self, obj): | |
return { | |
'data': obj.nodes, | |
'self': obj | |
} | |
def get_nodes_to_add_remove(self, nodes, new_nodes): | |
diff = relationship_diff( | |
current_items={node._id: node for node in nodes}, | |
new_items={node['_id']: node for node in new_nodes} | |
) | |
nodes_to_add = [] | |
for node_id in diff['add']: | |
node = Node.load(node_id) | |
if not node: | |
raise NotFound | |
nodes_to_add.append(node) | |
return nodes_to_add, diff['remove'].values() | |
def get_eligible_nodes(self, nodes, add): | |
return [ | |
descendant | |
for node in (nodes + add) | |
for descendant in node.get_descendants_recursive() | |
if descendant._parent_node in (nodes + add) | |
] | |
def create(self, validated_data): | |
instance = self.context['view'].get_object() | |
view_only_link = instance['self'] | |
nodes = instance['data'] | |
user = self.context['request'].user | |
new_nodes = validated_data['data'] | |
add, remove = self.get_nodes_to_add_remove( | |
nodes=nodes, | |
new_nodes=new_nodes | |
) | |
if not len(add): | |
raise RelationshipPostMakesNoChanges | |
eligible_nodes = self.get_eligible_nodes(nodes, add) | |
for node in add: | |
if not node.has_permission(user, 'admin'): | |
raise PermissionDenied | |
if node not in eligible_nodes: | |
raise ValidationError(detail='The node {0} cannot be affiliated with this VOL because it is not a child of the associated VOL nodes.'.format(node._id)) | |
view_only_link.nodes.append(node) | |
view_only_link.save() | |
return self.make_instance_obj(view_only_link) | |
def update(self, instance, validated_data): | |
view_only_link = instance['self'] | |
nodes = instance['data'] | |
user = self.context['request'].user | |
new_nodes = validated_data['data'] | |
add, remove = self.get_nodes_to_add_remove( | |
nodes=nodes, | |
new_nodes=new_nodes | |
) | |
for node in remove: | |
if not node.has_permission(user, 'admin'): | |
raise PermissionDenied | |
view_only_link.nodes.remove(node) | |
view_only_link.save() | |
nodes = [Node.load(node) for node in view_only_link.nodes] | |
eligible_nodes = self.get_eligible_nodes(nodes, add) | |
for node in add: | |
if not node.has_permission(user, 'admin'): | |
raise PermissionDenied | |
if node not in eligible_nodes: | |
raise ValidationError(detail='The node {0} cannot be affiliated with this VOL because it is not a child of the associated VOL nodes.'.format(node._id)) | |
view_only_link.nodes.append(node) | |
view_only_link.save() | |
return self.make_instance_obj(view_only_link) | |
class Meta: | |
type_ = 'nodes' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment