我如何创建一个带有外键的 Django 模型,它不会将删除级联到它的孩子?

2021-12-19 00:00:00 django django-models mysql

我的一个具有 ForeignKey 的模型实际上是其他表上的 MySQL 视图.我遇到的问题是,当我从这些表中删除数据时,Django,如 "删除对象" 文档...

One of my models which has ForeignKey's is actually a MySQL view on other tables. The problem I'm running into is that when I delete data from these tables, Django, as described in the "deleting objects" documentation...

当 Django 删除一个对象时,它模拟 SQL 的行为约束 ON DELETE CASCADE -- in换句话说,任何具有指向对象的外键被删除将被删除

When Django deletes an object, it emulates the behavior of the SQL constraint ON DELETE CASCADE -- in other words, any objects which had foreign keys pointing at the object to be deleted will be deleted along with it.

...试图从我的视图中删除行,这当然不能,因此引发错误:

...tries to remove rows from my view, which of course it can't, and so throws the error:

mysql_exceptions.OperationalError '>=(1395, "Can not delete from join view 'my_db.my_mysql_view'"'

有什么方法可以在模型上指定 ForeignKey 约束,它会为我提供所有 Django 魔法,但不会级联删除到它上面?或者,有没有办法让 MySQL 忽略从我的视图中删除一行的命令而不是引发错误?

Is there any way to specify a ForeignKey constraint on a model which will provide me with all the Django wizardry, but will not cascade deletes onto it? Or, is there a way to ask MySQL to ignore the commands to delete a row from my view instead of raising an error?

推荐答案

Harold 的回答为我指明了正确的方向.这是我实现它的方式的草图(在法国遗留数据库上,因此命名约定有点奇怪):

Harold's answer pointed me in the right direction. This is a sketch on the way I implemented it (on a french legacy database, hence the slightly odd naming convention):

class Factures(models.Model):
    idFacture = models.IntegerField(primary_key=True)
    idLettrage = models.ForeignKey('Lettrage', db_column='idLettrage', null=True, blank=True)

class Paiements(models.Model):
    idPaiement = models.IntegerField(primary_key=True)
    idLettrage = models.ForeignKey('Lettrage', db_column='idLettrage', null=True, blank=True)

class Lettrage(models.Model):
    idLettrage = models.IntegerField(primary_key=True)

    def delete(self):
        """Dettaches factures and paiements from current lettre before deleting"""
        self.factures_set.clear()
        self.paiements_set.clear()
        super(Lettrage, self).delete()

相关文章