在 Django 2.0 如何处理 generic.DeleteView 中的 ProtectedError

Dea*_*ean 2 django django-models django-views

我有一个通用视图声明如下:

class CustomerDelete(LoginRequiredMixin,DeleteView):

    model = models.Customer
    success_url = reverse_lazy('customer-list')
Run Code Online (Sandbox Code Playgroud)

一个模型声明如下:

class Order(models.Model):

    Customer = models.ForeignKey(Customer, on_delete=models.PROTECT, default=None)
    Shop = models.ForeignKey(Shop, on_delete=models.PROTECT, default=None)
    Status = models.IntegerField(choices=STATUS);
    Reference = models.CharField(max_length=50)
    Date = models.DateTimeField(default=None)
    LastAuthorizationDate = models.DateTimeField(default=None, null=True)
    LastUpdated = models.DateTimeField(auto_now=True)
    def get_absolute_url(self):
        return reverse_lazy('order-view', None, [self.id])    

    def type(self):
        return 'Order'

    def Name(self):
        return self.Customer.Name + ' - ' + self.Shop.Name + ' - ' + self.Reference
Run Code Online (Sandbox Code Playgroud)

删除后,我收到以下异常:

ProtectedError at /customer/2/delete/(“无法删除模型 'Customer' 的某些实例,因为它们是通过受保护的外键引用的:'Order.Customer'”, , , , , ]>)

什么是最好的类方法来覆盖和捕获允许我重定向到附加错误的引用者的异常?

提前致谢。

Bur*_*lid 5

您需要覆盖该delete方法,以添加您的自定义逻辑:

class CustomerDelete(LoginRequiredMixin,DeleteView):

    model = models.Customer
    success_url = reverse_lazy('customer-list')
    error_url = reverse_lazy('customer-has-orders-error')

    def get_error_url(self):
        if self.error_url:
            return self.error_url.format(**self.object.__dict__)
        else:
            raise ImproperlyConfigured(
               "No error URL to redirect to. Provide a error_url.")

    def delete(self, request, *args, **kwargs):
            """
            Call the delete() method on the fetched object and then redirect. 
            """
           self.object = self.get_object()
           success_url = self.get_success_url()
           error_url = self.get_error_url()
           try:
                self.object.delete()
                return HttpResponseRedirect(success_url)
           except models.ProtectedError:
                return HttpResponseRedirect(error_url)
Run Code Online (Sandbox Code Playgroud)

如果您要经常使用它,您可以使用上述逻辑创建自己的自定义 mixin。

此外,考虑在您的应用程序中实施软删除,以便记录不会立即从数据库中删除,而是标记为稍后删除 - 一旦它们被存档。否则,您可能会遇到业务逻辑问题。