我的一个拥有ForeignKey
的模型实际上是其他表上的MySQL视图。我遇到的问题是,当我从这些表中删除数据时,Django,如"deleting objects" documentation ...
当Django删除一个对象时,它 模拟SQL的行为 约束ON DELETE CASCADE - in 换句话说,任何具有的对象 指向对象的外键 被删除将被删除 它
...尝试从我的视图中删除行,当然它不能,所以抛出错误:
mysql_exceptions.OperationalError '>=(1395, "Can not delete from join view 'my_db.my_mysql_view'"'
有没有办法在模型上指定一个ForeignKey
约束,它将为我提供所有Django魔法,但是不会将删除级联到它上面?或者,有没有办法让MySQL忽略从我的视图中删除行而不是引发错误的命令?
答案 0 :(得分:23)
Django 1.3a1并通过ForeignKey
的{{3}}论证提供支持。
以下示例在删除外键时设置字段NULL
。有关更多选项,请参阅on_delete
。
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)
答案 1 :(得分:18)
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()
答案 2 :(得分:7)
Django的ForeignKey管理器有一个名为clear()的方法,它从相关的对象集中删除所有对象。首先调用,然后删除您的对象应该工作。依赖对象的外键设置为None(如果模型允许)。
这里有一个简短的描述: http://docs.djangoproject.com/en/dev/topics/db/queries/#following-relationships-backward
答案 3 :(得分:3)
仅供参考 - 在http://code.djangoproject.com/ticket/7539的django源存储库中存在对此的功能请求。看起来这个主题得到了一些关注。希望它将包含在未来的Django版本中。
该票据包括Django核心的补丁,用于为models.ForeignKey(...)实现“on_delete”可选参数,该参数允许您指定在删除指向模型时发生的情况,包括关闭默认的ON DELETE CASCADE行为
答案 4 :(得分:2)
好吧,看看删除方法
def delete(self):
assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname)
# Find all the objects than need to be deleted.
seen_objs = CollectedObjects()
self._collect_sub_objects(seen_objs)
# Actually delete the objects.
delete_objects(seen_objs)
我会说覆盖删除应该足够......未经测试的代码将是
def delete(self):
assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname)
# Find all the objects than need to be deleted.
seen_objs = CollectedObjects()
seen_objs.add(model=self.__class__, pk=self.pk, obj=self, parent_model=None)
# Actually delete the objects.
delete_objects(seen_objs)
答案 5 :(得分:1)
一种方法是在删除之前调用clear方法,documentation here基本上“清除”关系。 一个问题是:它本身不是汽车。你可以选择:每次你不想要级联时调用它,或者在每次删除之前使用pre_delete信号发送清除,当然它会在你想要删除时给你带来问题 - 级联。
或者你可以为django社区做贡献并添加关键字参数来删除,也许它会在django 1.3中?:D
答案 6 :(得分:0)
回复:http://code.djangoproject.com/ticket/7539
2010年6月的Django 1.2.1没有引起注意。我想我们需要“注意那个空间”。