2009-06-17 19 views
23

其中一個我的模型ForeignKey的實際上是其他表上的MySQL視圖。我遇到的問題是,當我從這些表中刪除數據,Django的,如"deleting objects" documentation描述...如何用ForeignKeys創建一個Django模型,該模型不會級聯刪除子項?

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.

...試圖從我的觀點刪除行,它能這當然「T,所以引發錯誤:

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

有什麼辦法能夠指定一個模式,將會爲我提供所有的Django的巫術一個ForeignKey約束,但不會級聯刪除到了嗎?或者,有沒有辦法讓MySQL忽略命令從我的視圖中刪除一行而不是引發錯誤?

回答

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

請參閱`on_delete = models.SET_NULL`:https://docs.djangoproject.com/en/1.4/ref/models/fields/#foreignkey(sinze 1.3版本) – danihp 2012-08-07 14:05:28

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) 
+0

(是的,它是一種混亂的;我說應該有一個參數ForeignKey的...填寫Django的門票系統爲它的功能要求;)) 無論如何,對於你的看法的情況下, ,看看這個bug /補丁:http://code.djangoproject.com/ticket/10829 – Almad 2009-06-17 10:46:12

+0

忘記查詢集刪除。 – 2011-06-14 01:44:50

1

一種方法是刪除,documentation here基本上「清除」的關係之前調用Clear方法。 一個問題認爲:它不是自動的。您可以選擇:每次不需要級聯時調用它,或者在每次刪除之前使用pre_delete信號發送清除,當您想要刪除級聯時它會給您帶來問題。

或者你可以向Django的社區,並添加關鍵字參數刪除,也許這將是在Django 1.3:d

3

僅供參考 - 在http://code.djangoproject.com/ticket/7539在Django的源庫中存在此功能請求。看起來這個話題正在引起一些關注。希望它會包含在未來的Django發佈中。

票據中包含Django核心的補丁,用於爲models.ForeignKey(...)實現一個「on_delete」可選參數,該參數允許您指定刪除指向Model時發生的情況,包括關閉默認ON DELETE CASCADE行爲。

23

Django 1.3a1並支持這個通過ForeignKeyon_delete的論點。

以下示例在刪除外鍵時設置字段NULL。請參閱documentation瞭解更多選項。

user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)