1

Dans this topic J'ai trouvé un bon moyen d'empêcher la suppression en cascade d'objets liés, quand ce n'est pas nécessaire.Suppression en cascade de clés étrangères Django et paramètre "related_name" (bug?)

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() 

Mais cette méthode semble échouer lorsque nous utilisons le champ ForeignKey avec le paramètre "related_name". Comme il me semble, la méthode "clear()" fonctionne bien et enregistre l'instance de l'objet "désassocié". Mais alors, tout en supprimant, django utilise une autre copie mémorisée de cet objet même et comme il est toujours associé à un objet, nous essayons de supprimer - whooooosh! ... bye-bye à des parents :)

Base de données a été arcitectured avant moi, et de manière un peu étrange, donc je ne peux pas échapper à ces "related_names" dans un laps de temps raisonnable. Quelqu'un a entendu parler de solution de contournement pour un tel problème?

+0

Notez que dans les versions récentes de Django, on utiliserait 'on_delete = SET_NULL' au lieu de ce hack. – bouke

Répondre

2

Qu'en est-il de relire à nouveau l'objet et de le supprimer?

to_delete = self.__class__.objects.get(pk=self.pk) 
to_delete.delete() 

De cette façon, l'objet supprimé est une nouvelle copie. Le problème est de faire correctement toutes les autres choses que la méthode originale delete() doit faire, comme l'appel de signal, retourner la bonne valeur, etc ...

+0

En fait, cette méthode fonctionne pour moi. J'utilise Django 1.2 (checkout de la branche stable). En outre, il est documenté lors de la suppression d'un objet à l'aide d'actions (directement dans la liste des objets admin, pas dans le formulaire de modification), la méthode delete() de l'objet n'est pas appelée, car elle est supprimée (QuerySet.delete() –

+0

Merci Mandx, je vais essayer. Je ne sais pas quand, puisque ma ligne de travail est allé faaaaar au-delà de ce morceau de code :) – Wiseman