Django - 删除对象而不删除其相关对象

时间:2010-09-10 22:18:38

标签: django django-models

我有两种模式:

class Client(models.Model):
    some_field = models.CharField()

class Ticket(models.Model):
    client = models.ForeignKey(Client)

Ticket在我的系统中 FOREVER ,但我希望用户能够删除他们不再需要的客户端。目前,它将删除Client创建的所有故障单。

  1. 这是一个坏主意(从架构上讲),我应该将它们标记为not_needed或其他东西吗?
  2. 如果这不是一个坏主意,最好的方法是什么,同时保持DRY。我不想为每个执行此操作的模型覆盖delete(),但如果我必须(如果这是唯一的方法,最好的方式是什么)。

3 个答案:

答案 0 :(得分:10)

所以这个问题很老了,但是如果有人碰到它(就像我做的那样):从Django 1.3开始,你可以使用on_delete参数用于ForeignKey模型,如上所述{{3 }}

答案 1 :(得分:5)

django.contrib.auth模块必须在User模型中处理同样的问题。他们的解决方案是:

class User(models.Model):
    # ...
    is_active = models.BooleanField(default=True)
    # ...

所以“删除”User只是将is_active设置为False。与User一起使用的所有内容都需要检查is_active

对于记录,我认为在这种情况下删除Client错误的想法

但是为了争论,如果删除Client,那么它的相关Ticket首先需要成为无客户端。将Ticket的模型更改为:

class Ticket(models.Model):
    client = models.ForeignKey(Client, null=True, blank=True, 
        related_name='tickets')

然后,要删除Client,请执行:

for ticket in clientToDelete.tickets:
    ticket.client = None
    ticket.save()
clientToDelete.delete()

您可以将此代码放入Client的{​​{1}}方法中,但如果您执行大量(即基于QuerySet)删除delete s,它将被跳过。

答案 2 :(得分:0)

就个人而言,我认为这是一个坏主意(你有孤儿票记录)。我只会将这些客户标记为“not_needed”或“已删除”。您还可以获得以后“取消删除”这些客户端的额外好处。