def attach(self, request, *args, **kwargs): created = False parent = self.get_parent_object() relationship = getattrd(parent, self.relationship) data = request.data sub_id, res = self.attach_validate(request) if res: return res # Create the sub object if an ID is not provided. if not sub_id: response = self.create(request, *args, **kwargs) if response.status_code != status.HTTP_201_CREATED: return response sub_id = response.data['id'] data = response.data try: location = response['Location'] except KeyError: location = None created = True # Retrive the sub object (whether created or by ID). sub = get_object_or_400(self.model, pk=sub_id) # Verify we have permission to attach. if not request.user.can_access(self.parent_model, 'attach', parent, sub, self.relationship, data, skip_sub_obj_read_check=created): raise PermissionDenied() # Verify that the relationship to be added is valid. attach_errors = self.is_valid_relation(parent, sub, created=created) if attach_errors is not None: if created: sub.delete() return Response(attach_errors, status=status.HTTP_400_BAD_REQUEST) # Attach the object to the collection. if sub not in relationship.all(): relationship.add(sub) if created: headers = {} if location: headers['Location'] = location return Response(data, status=status.HTTP_201_CREATED, headers=headers) else: return Response(status=status.HTTP_204_NO_CONTENT)
def unattach_by_id(self, request, sub_id): parent = self.get_parent_object() parent_key = getattr(self, 'parent_key', None) relationship = getattrd(parent, self.relationship) sub = get_object_or_400(self.model, pk=sub_id) if not request.user.can_access(self.parent_model, 'unattach', parent, sub, self.relationship, request.data): raise PermissionDenied() if parent_key: sub.delete() else: relationship.remove(sub) return Response(status=status.HTTP_204_NO_CONTENT)
def unattach_by_id(self, request, sub_id): parent = self.get_parent_object() parent_key = getattr(self, 'parent_key', None) relationship = getattrd(parent, self.relationship) sub = get_object_or_400(self.model, pk=sub_id) if not request.user.can_access(self.parent_model, 'unattach', parent, sub, self.relationship, request.data): raise PermissionDenied() # Verify that removing the relationship is valid. unattach_errors = self.is_valid_removal(parent, sub) if unattach_errors is not None: return Response(unattach_errors, status=status.HTTP_400_BAD_REQUEST) if parent_key: sub.delete() else: relationship.remove(sub) return Response(status=status.HTTP_204_NO_CONTENT)
def attr(inst): return getattrd(inst, attr_path)
def get_sublist_queryset(self, parent): return getattrd(parent, self.relationship).distinct()
def get_queryset(self): parent = self.get_parent_object() self.check_parent_access(parent) qs = self.request.user.get_queryset(self.model).distinct() sublist_qs = getattrd(parent, self.relationship).distinct() return qs & sublist_qs