models.CASCADE
似乎在我尝试在删除视图中删除父对象时无法正常工作。
我有两个模型。 ExceptionReport和ExceptionReportHistroy。用户可以创建报告,如果满足条件,则将创建一个历史对象。用户可以删除报告,并且删除后,所有关联的历史记录对象都应删除,但是当用户尝试删除时,出现此错误:
(1451, 'Cannot delete or update a parent row: a foreign key constraint fails (`lp`.`reports_exceptionreporthistory`, CONSTRAINT `reports_exceptionrep_report_id_99f21d10_fk_lp_except` FOREIGN KEY (`report_id`) REFERENCES `lp_exception_reports` (`id`))')
我不知道为什么,因为on_delete = models.CASCADE
型号:
class ExceptionReports(models.Model):
from_field = models.CharField(max_length=100, blank=True)
emails = EmailListField(max_length=800)
description = models.CharField(max_length=100)
user = models.ForeignKey(User, on_delete=models.CASCADE)
...
class ExceptionReportHistory(models.Model):
created_date = models.DateTimeField(default=now)
report = models.ForeignKey(ExceptionReports, on_delete=models.CASCADE)
message = models.TextField(blank=True)
...
查看:
class ExceptionReportDeleteView(LoginRequiredMixin, DeleteView):
model = ExceptionReports
template_name = "reports/delete.html"
success_url = reverse_lazy('reports:exceptionreport_list')
success_message = "Exception Report deleted successfully."
URL:
path('exceptionreports/', include([
path('', login_required(views.ExceptionReportListView.as_view()), name='exceptionreport_list'),
path('add/', login_required(views.ExceptionReportCreateView.as_view()), name='exceptionreport_create'),
path('<int:pk>/', include([
path('update/', login_required(views.ExceptionReportUpdateView.as_view()), name='exceptionreport-update'),
path('delete/', login_required(views.ExceptionReportDeleteView.as_view()), name='exceptionreport-delete'),
])),
])),
在删除视图中,应该提示用户关联的历史对象,这些对象也将被删除,但不会发生,相反,我收到一个IntegrityError
否则,在另一个具有类似设置的DeleteView中。如果用户正在删除带有与之关联的子对象的对象。系统会提示他们相关的对象,这些对象也将被删除。我将附上输出的快照。该代码与我的代码非常相似,但是设置了Permissions_required并继承了DeleteMixin。我尝试使用这种方法,但仍然遇到该错误。 screenshot of UI
class DeleteHelperMixin(object):
def delete(self, request, *args, **kwargs):
"""
Call the delete() method on the fetched object and then redirect to the
success URL.
Also use the success message.
"""
self.object = self.get_object()
success_url = self.get_success_url()
self.object.delete()
messages.success(request, self.success_message)
return HttpResponseRedirect(success_url)
@staticmethod
def get_deleted_objects(objs, using):
"""
Find all objects related to ``objs`` that should also be deleted. ``objs``
must be a homogeneous iterable of objects (e.g. a QuerySet).
Return a nested list of strings suitable for display in the
template with the ``unordered_list`` filter.
This is simplified from a method by the same name that the Django admin uses.
"using" means the key in the DATABASES setting.
"""
collector = NestedObjects(using=using)
collector.collect(objs)
def format_callback(obj):
return '%s: %s' % (capfirst(obj._meta.verbose_name), obj)
to_delete = collector.nested(format_callback)
protected = [format_callback(obj) for obj in collector.protected]
model_count = {model._meta.verbose_name_plural: len(objs) for model, objs in collector.model_objs.items()}
return to_delete, model_count, protected
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
obj = self.get_object()
# Get a queryset so that we can get the database alias
db_alias = self.model.objects.filter(pk=obj.pk).db
to_delete, model_count, protected = self.get_deleted_objects([obj], db_alias)
context.update({
'object_name': self.model._meta.verbose_name,
'objs_to_be_deleted': to_delete,
})
return context
更新: 我覆盖了delete方法并首先删除了相关对象,但仍然收到IntegrityError。
我不确定这是否是解决问题的真正原因,但是当我第一次创建模型并迁移数据库时,我没有设置db_table
名称,然后我更改了名称并已迁移但忘记删除默认名称的旧表。删除默认表并使用自定义数据库名称截断该表后,此问题已解决。