J'ai un problème parce que je supprime un widget en utilisant some_widget_instance.delete (). J'ai également un modèle appelé WidgetFile avec une méthode override delete () afin de pouvoir supprimer des fichiers de mon disque dur lorsqu'un fichier WidgetFile est supprimé. Le problème que je rencontre est que si je supprime un widget, il contient des fichiers Widget comme ceci:
class WidgetFile(models.Model):
widget = models.ForeignKey(Widget)
Eh bien, lorsque je supprime ce widget, ce sont des fichiers Widget qui sont supprimés, mais la méthode delete () ne déclenche pas et ne gère pas le contenu de mon disque dur supplémentaire. Toute aide est très appréciée.
Je l'ai compris. Je viens de mettre ceci sur ce modèle de widget:
def delete(self):
files = WidgetFile.objects.filter(widget=self)
if files:
for file in files:
file.delete()
super(Widget, self).delete()
Cela a déclenché la méthode delete () nécessaire sur chacun des objets liés, entraînant ainsi la suppression du code par mon fichier personnalisé. La base de données coûte certes plus cher, mais quand vous essayez de supprimer des fichiers sur un disque dur, ce n'est pas une grosse dépense de frapper la base de données quelques fois de plus.
Je fais la même chose et j'ai remarqué une pépite dans la documentation Django à laquelle vous devriez penser.
Remplacement des méthodes de modèle prédéfinies
Redéfinition de la suppression Notez que la méthode delete () d'un objet n'est pas nécessairement appelée lors de la suppression d'objets en bloc à l'aide d'un QuerySet. Pour que la logique de suppression personnalisée soit exécutée, vous pouvez utiliser les signaux pre_delete et/ou post_delete.
Cela signifie que votre extrait ne fera pas toujours faire ce que vous voulez. Utiliser Signaux est une meilleure option pour traiter les suppressions.
Je suis allé avec ce qui suit:
import shutil
from Django.db.models.signals import pre_delete
from Django.dispatch import receiver
@receiver(pre_delete)
def delete_repo(sender, instance, **kwargs):
if sender == Set:
shutil.rmtree(instance.repo)
L'utilisation de clear()
avant la suppression supprime tous les objets du jeu d'objets associés.
voir Django-suivantes-relations-arriérées
exemple:
group.link_set.clear()
group.delete()
Cela ne semble avoir du sens que si un Widget est connecté à un WidgetFile exactement. Dans ce cas, vous devez utiliser un OneToOneField
from Exemples on-to-one:
# Delete the restaurant; the waiter should also be removed
>>> r = Restaurant.objects.get(pk=1)
>>> r.delete()
Juste pour jeter un moyen possible autour de ce problème: pré-supprimersignaler . (Cela ne signifie nullement qu'il n'y a pas de solution réelle.)
Il devrait ressembler à ce qui est décrit sur le site Django :
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def save(self, *args, **kwargs):
do_something()
super(Blog, self).save(*args, **kwargs) # Call the "real" save() method.
do_something_else()
http://docs.djangoproject.com/fr/dev/topics/db/models/#overriding-predefined-model-methods
vous avez oublié de passer des arguments
Est-ce que some_widget_instance
et une instance de Widget
ou de WidgetFile
? Parce que s'il s'agit d'une instance de Widget
, il n'obtiendra pas votre fonction delete()
personnalisée, qui se trouve dans la classe WidgetFile
.
À partir de Django 1.9, si vous définissez simplement on_delete=models.CASCADE
pour le champ, tous les objets liés seront supprimés.