2017-07-04 5 views
0

Lorsque l'utilisateur crée un produit, plusieurs actions doivent être effectuées dans la méthode save() avant d'appeler super(Product,self).save(*args,**kwargs).Dois-je préférer un signal général plutôt que plusieurs signaux spécifiques?

Je ne suis pas sûr si je devrais utiliser un seul signal pre_save pour faire toutes ces actions ou il est préférable de créer un signal pour chacune de ces actions séparément.

exemple simple (je vais remplacer par des signaux save overrides):

class Product(..): 
    def save(...): 
     if not self.pk: 
      if not self.category: 
       self.category = Category.get_default() 
      if not self.brand: 
       self.brand = 'NA' 
     super(Product,self).save(*args,**kwargs) 
     ... 

SO

@receiver(pre_save,sender=Product) 
def set_attrs(instance,**kwargs): 
    if kwargs['created']: 
     instance.category = Category.get_default() 
     instance.brand = 'NA' 

OU

@receiver(pre_save,sender=Product) 
def set_category(instance,**kwargs): 
    if kwargs['created']: 
     instance.category = Category.get_default() 

@receiver(pre_save,sender=Product) 
def set_brand(instance,**kwargs): 
    if kwargs['created']: 
     instance.brand = 'NA' 

Cette est juste un exemple simple. Dans ce cas, le set_attrs général devrait être assez probablement, mais il y a des situations plus complexes avec différentes actions comme la création userprofile pour user puis userplan etc.

Y at-il meilleur conseil pratique pour cela? Tes opinions?

+0

Je dirais que pour maintenabilité il serait préférable de les séparer. Mais j'essaie généralement d'éviter d'utiliser des signaux et d'utiliser plutôt des méthodes de gestion, etc. –

Répondre

0

Pour mettre les faits sur simplement, il pourrait être fait comme un seul conseil,

Si une action sur un modèle de l'instance affecte un autre modèle, les signaux sont les plus propres moyen d'aller sur. C'est un exemple où vous pouvez aller avec un signal, parce que vous pourriez vouloir éviter some_model.save() appel de la méthode save() de another_model, si vous savez ce que je veux dire.

Pour élaborer un exemple, lors de la substitution des méthodes save(), la tâche courante consiste à créer des slugs à partir de certains champs du modèle. Si vous devez implémenter ce processus sur plusieurs modèles, l'utilisation d'un signal pre_save serait un avantage plutôt qu'un codage en dur dans la méthode save() de chaque modèle.

De même, pour les opérations en masse, ces signaux et procédés ne sont pas nécessairement appelés.

De la documentation,

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 des objets en vrac à 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'existe 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é.

Pour plus référence,