Я не думаю, что можно получить нужную информацию из функции PROTECT, кроме извлечения ее из сгенерированного сообщения с некоторыми регулярными выражениями.
Что возможно для создания собственного подкласса ProtectedError и ваш собственный метод PROTECT, например:
class MyProtectError(models.deletion.ProtectedError):
def __init__(self, msg, protected_objects, **kwargs):
self.kwargs = kwargs
super().__init__(msg, protected_objects)
def MY_PROTECT(collector, field, sub_objs, using):
kwargs = {
'field': field,
'sub_objs': sub_objs,
'using': using
}
raise MyProtectError(
"Cannot delete some instances of model '%s' because they are "
"referenced through a protected foreign key: '%s.%s'" % (
field.remote_field.model.__name__, sub_objs[0].__class__.__name__, field.name
),
sub_objs, **kwargs
)
Затем используйте MY_PROTECT
в вашей модели, например,
class ProtectChild(models.Model):
title = models.CharField(max_length=100)
master = models.ForeignKey(ProtectMaster, on_delete=MY_PROTECT)
и используйте свой пользовательский класс в перезаписанном delete()
метод:
def delete(self, request, *args, **kwargs):
self.object = self.get_object()
try:
self.object.delete()
messages.error(self.request, 'Ok')
except MyProtectError as e:
messages.error(self.request, 'Whoops')
print('Model', e.kwargs['field'].remote_field.model.__name__)
print('Field', e.kwargs['field'].name)
print('Submodel', e.kwargs['sub_objs'][0].__class__.__name__)
return render(request, 'myurl')