def CASCADE_NEW(collector, field, sub_objs, using): from django.db.models.deletion import ProtectedError raise ProtectedError( "Cannot delete some instances of model '%s' because " "they are referenced through a protected foreign key: '%s.%s'" % (field.rel.to.__name__, sub_objs[0].__class__.__name__, field.name), sub_objs)
def test_perform_destroy_raises_for_protectederror(self): protected = Mock() protected.model._meta.label = 'testmodel' protected.values_list.return_value = [1, 2] exception = ProtectedError('some db constraint', protected_objects=protected) exception.protected_objects = protected instance = Mock() instance.delete.side_effect = exception with pytest.raises(ValidationError) as exc: DestroyModelMixin().perform_destroy(instance) assert exc.message == 'Referenced by protected testmodel 1, 2' assert instance.delete.call_count == 1
def test_perform_destroy_failure(self, mocker): p_super = mocker.patch('risks.views.super') protected_error = ProtectedError('some msg', 'some objs') p_super.return_value.perform_destroy.side_effect = protected_error with pytest.raises(CannotDeleteAlreadyInUse): FieldTypeList.perform_destroy(None, 'instance to destroy')
def test_reset_exception(self): """ Some widgets can't be deleted. We should still be able to reset. """ tracker, commit1 = make_commit(self.widgy_site, datetime.timedelta(days=-1)) with mock.patch.object(tracker.working_copy.content, 'delete') as delete: delete.side_effect = ProtectedError("can't delete", []) tracker.reset()
def protect_basket_items(sender, instance, **kwargs): """ Protect against deletion of products already added to basket. """ from django.contrib.contenttypes.models import ContentType from salesman.basket.models import BasketItem content_type = ContentType.objects.get_for_model(sender) items = BasketItem.objects.filter(product_content_type=content_type, product_id=instance.id) if items.count(): msg = f"Cannot delete the product '{instance}' because it is added to basket." raise ProtectedError(msg, items)
def get_related_objects(obj, using=DEFAULT_DB_ALIAS, collector=None): """Method to get related objects. This code is based on https://github.com/makinacorpus/django-safedelete It forbids to delete object if it has protected related objects. """ if not collector: collector = get_collector(obj, using) if collector.protected: raise ProtectedError( ('Cannot delete object "{obj}" as it has protected relations.'. format(obj=obj)), list(collector.protected)) def flatten(elem): if isinstance(elem, list): return itertools.chain.from_iterable(map(flatten, elem)) elif obj != elem: return (elem, ) return () return flatten(collector.nested())
def prevent_deletes(sender, instance, **kwargs): raise ProtectedError("Not allowed to delete.", [instance])
def role_soft_delete_protect(instance: RoleModel, **kwargs): if instance.deleted: users_all = instance.users.all() if users_all: raise ProtectedError("role has users.", users_all)
def delete_is_available_returned(sender: FlatPage, instance: FlatPage, **kwargs): url = instance.url[1:] if instance.url.startswith("/") else instance.url if any(url == str(urlpattern.pattern) for urlpattern in urlpatterns): raise ProtectedError("This page cannot be deleted", {instance})