2008-10-04 9 views
61

Je n'arrive pas à résoudre ce problème. En ce moment j'ai quelques modèles qui ressemble un peu comme ceci:Signaux Django vs méthode de sauvegarde prioritaire

def Review(models.Model) 
    ...fields... 
    overall_score = models.FloatField(blank=True) 

def Score(models.Model) 
    review = models.ForeignKey(Review) 
    question = models.TextField() 
    grade = models.IntegerField() 

Un examen est a plusieurs « scores », la overall_score est la moyenne des scores. Lorsqu'un avis ou un score est enregistré, je dois recalculer la moyenne globale_score. En ce moment j'utilise une méthode de sauvegarde surchargée. Y aurait-il des avantages à utiliser le répartiteur de signaux de Django?

Répondre

67

Les signaux de sauvegarde/suppression sont généralement favorables dans les situations où vous devez apporter des modifications qui ne sont pas complètement spécifiques au modèle en question ou qui pourraient être appliquées à des modèles qui ont quelque chose en commun ou peuvent être configurés des modèles.

Une tâche courante dans les méthodes save remplacées est la génération automatique de slugs à partir d'un champ de texte dans un modèle. C'est un exemple de quelque chose qui, si vous deviez l'implémenter pour un certain nombre de modèles, aurait avantage à utiliser un signal pre_save, où le gestionnaire de signal pourrait prendre le nom du champ slug et le nom du champ pour générer le slug de . Une fois que vous avez quelque chose comme cela en place, toute fonctionnalité améliorée que vous mettez en place s'appliquera également à tous les modèles - par ex. en regardant la limace que vous êtes sur le point d'ajouter pour le type de modèle en question, pour assurer l'unicité.

Les applications réutilisables bénéficient souvent de l'utilisation de signaux - si la fonctionnalité qu'elles fournissent peut être appliquée à n'importe quel modèle, elles ne veulent généralement pas (sauf si c'est inévitable) que les utilisateurs modifient directement leurs modèles pour bénéficier de il.

Avec django-mptt, par exemple, j'utilise le signal pre_save pour gérer un ensemble de champs qui décrivent une structure arborescente pour le modèle qui est sur le point d'être créé ou mis à jour et le signal pre_delete pour éliminer les détails de la structure de l'arbre pour l'objet supprimé et son sous-arbre entier d'objets avant et ils sont supprimés. En raison de l'utilisation de signaux, les utilisateurs n'ont pas besoin d'ajouter ou de modifier les méthodes save ou delete sur leurs modèles pour que cette gestion soit faite pour eux, ils doivent simplement indiquer à django-mptt quels modèles ils veulent gérer.

3

Si vous utilisez des signaux, vous pourrez mettre à jour le score de révision chaque fois que le modèle de score associé est enregistré. Mais si je n'ai pas besoin d'une telle fonctionnalité, je ne vois aucune raison de mettre cela en évidence, c'est plutôt joli.

2

C'est une sorte de dénormalisation. Regardez ce pretty solution. Définition du champ de composition en place.

-20

Les signaux sont utiles lorsque vous devez exécuter un processus à long terme et que vous ne voulez pas empêcher votre utilisateur d'attendre la fin de la sauvegarde.

+8

Non, à moins que vous signaux bloc engendrez threads explicitement. – muhuk

+8

@muhuk a raison, les signaux bloquent vos processus. Si vous souhaitez éviter les processus bloqués, utilisez des outils tels que gevent, céleri ou d'autres outils asynchrones. – pydanny

+1

Je lui donne un -1 à cause des points de muhuk et pydanny. On dirait que c'est un mauvais conseil. La demande ne finira pas jusqu'à ce que le traitement du signal soit terminé. Donc le céleri semble être une bonne solution, ce que j'utilise normalement dans mes projets django. –

11

Vous avez demandé:

Y aurait-il des avantages à utiliser le répartiteur de signaux de Django?

Je trouve cela dans les django docs:

méthodes de modèle OPPOSER ne sont pas appelés sur les opérations en vrac

Notez que la méthode de suppression() pour un objet est pas nécessairement appelé lors de la suppression d'objets en bloc à l'aide d'un QuerySet ou à la suite d'une suppression en cascade .Pour vous assurer que la logique de suppression personnalisée est exécutée, vous pouvez utiliser les signaux pre_delete et/ou post_delete.

Malheureusement, il n'y a pas une solution de contournement lors de la création ou la mise à jour objets en vrac, car aucun de sauvegarde(), pre_save et post_save sont appelés .

De: Overriding predefined model methods

+2

La vue de liste d'admin de Django utilise la suppression en bloc ... a été confondue jusqu'à ce qu'elle soit tombée sur cette friandise. –

+0

indique également "Malheureusement, il n'y a pas de solution de contournement lors de la création ou de la mise à jour d'objets en masse, car aucun save(), pre_save et post_save n'est appelé." - donc je ne pense pas que ce soit un compromis entre ces méthodes. – Cory

Questions connexes