Django-fr

Forum

  • Accueil
  • » Django-fr
  • » Exécution multiple des signaux lorsqu'on les définie dans models.py ?

#1 15-05-2009 10:57:16

Lior Gradstein
Membre
Inscription : 11-08-2010
Messages : 2

Exécution multiple des signaux lorsqu'on les définie dans models.py ?

Bonjour,

J'attache une methode à un signal avec la commande
"signals.pre_save.connect(ma_methode, sender=MonModele)", que j'inclue dans
mon fichier models.py:

def ma_methode(sender, instance, signal, *args, **kwargs):
   print "Hello world"

from django.db.models import signals
signals.pre_save.connect(ma_methode, sender=MyModel)


Mon problème: si je mets un print dans cette methode, je vois qu'elle est
appelée plusieurs fois lors de la création de mon modele (soumission de mon
formulaire), alors qu'il ne devrait y passer qu'une fois.

La raison: j'ai mis ce signals.pre_save.connect() à la fin de mon models.py,
ce qui fait qu'il est exécuté dès que dans un autre module je fais un "from
models import MyModel" (par exemple dans mon form.py, ce que, je suppose,
tout le monde fait). Pourtant, lorsque je regarde dans ce qui se fait dans
les autres projets, le placement dans le models.py est recommandé.

Alors comment est-ce possible ? Je ne souhaite pas que ma méthode soit
appelée plusieurs fois !

Merci,
Luc

Hors ligne

#2 16-05-2009 17:37:33

Stephane Bunel
Membre
Inscription : 11-08-2010
Messages : 11

Re : Exécution multiple des signaux lorsqu'on les définie dans models.py ?

Le vendredi 15 mai 2009 11:57:16, Lior Gradstein a écrit :
> Bonjour,
>
> J'attache une methode à un signal avec la commande
> "signals.pre_save.connect(ma_methode, sender=MonModele)", que j'inclue dans
> mon fichier models.py:
>
> def ma_methode(sender, instance, signal, *args, **kwargs):
>    print "Hello world"
>
> from django.db.models import signals
> signals.pre_save.connect(ma_methode, sender=MyModel)
>
>
> Mon problème: si je mets un print dans cette methode, je vois qu'elle est
> appelée plusieurs fois lors de la création de mon modele (soumission de mon
> formulaire), alors qu'il ne devrait y passer qu'une fois.
>
> La raison: j'ai mis ce signals.pre_save.connect() à la fin de mon models.py,
> ce qui fait qu'il est exécuté dès que dans un autre module je fais un "from
> models import MyModel" (par exemple dans mon form.py, ce que, je suppose,
> tout le monde fait). Pourtant, lorsque je regarde dans ce qui se fait dans
> les autres projets, le placement dans le models.py est recommandé.
>
> Alors comment est-ce possible ? Je ne souhaite pas que ma méthode soit
> appelée plusieurs fois !

J'ai rencontré ce cas. Il est en fait très logique car le dispatcher est
sollicité à chaque import et enregistre donc plusieurs fois les signaux.

Pour éviter d'enregistrer plusieurs fois le même signal il suffit de lui donner
un identifiant au moment de l'enregistrer.

Ainsi le dispatcher pourra alors se rendre compte, grâce à l'identifiant, si
l'on tente d'enregistrer plusieurs fois le même signale.

Exemple:

signals.post_save.connect( person_post_save_callback,
    sender = Person,
    dispatch_uid = 'person_post_save_callback' )

Je donne le nom de la méthode invoquée comme identifiant mais c'est un choix
personnel et arbitraire.

Stéphane Bunel.
(...)

Hors ligne

#3 16-05-2009 21:00:07

Benoit Chesneau
Membre
Inscription : 11-08-2010
Messages : 57

Re : Exécution multiple des signaux lorsqu'on les définie dans models.py ?

Le 16 mai 2009 18:37, Stéphane Bunel <stephane+djangofr _AT_ bpf.st> a écrit :
> Le vendredi 15 mai 2009 11:57:16, Lior Gradstein a écrit :
>> Bonjour,
>>
>> J'attache une methode à un signal avec la commande
>> "signals.pre_save.connect(ma_methode, sender=MonModele)", que j'inclue dans
>> mon fichier models.py:
>>
>> def ma_methode(sender, instance, signal, *args, **kwargs):
>>    print "Hello world"
>>
>> from django.db.models import signals
>> signals.pre_save.connect(ma_methode, sender=MyModel)
>>
>>
>> Mon problème: si je mets un print dans cette methode, je vois qu'elle est
>> appelée plusieurs fois lors de la création de mon modele (soumission de mon
>> formulaire), alors qu'il ne devrait y passer qu'une fois.
>>
>> La raison: j'ai mis ce signals.pre_save.connect() à la fin de mon models.py,
>> ce qui fait qu'il est exécuté dès que dans un autre module je fais un "from
>> models import MyModel" (par exemple dans mon form.py, ce que, je suppose,
>> tout le monde fait). Pourtant, lorsque je regarde dans ce qui se fait dans
>> les autres projets, le placement dans le models.py est recommandé.
>>
>> Alors comment est-ce possible ? Je ne souhaite pas que ma méthode soit
>> appelée plusieurs fois !
>
> J'ai rencontré ce cas. Il est en fait très logique car le dispatcher est
> sollicité à chaque import et enregistre donc plusieurs fois les signaux.
>
> Pour éviter d'enregistrer plusieurs fois le même signal il suffit de lui donner
> un identifiant au moment de l'enregistrer.
>
> Ainsi le dispatcher pourra alors se rendre compte, grâce à l'identifiant, si
> l'on tente d'enregistrer plusieurs fois le même signale.
>
> Exemple:
>
> signals.post_save.connect( person_post_save_callback,
>    sender = Person,
>    dispatch_uid = 'person_post_save_callback' )
>
> Je donne le nom de la méthode invoquée comme identifiant mais c'est un choix
> personnel et arbitraire.
>
> Stéphane Bunel.
> (...)
>
> _______________________________________________
> django mailing list
> django _AT_ lists.afpy.org
> http://lists.afpy.org/mailman/listinfo/django
>

rien de logique à cela si on on considère que id donne un identifiant
unique. Ceci dit comme vu sur irc models.mafonction ne renvoie pas le
même id que mafonction seul. D'ou le problème et la nécessité quand on
est pas homogène dans son code d'utiliser dispatch_uid.

Dans tous les cas il serait bien quand une personne a trouvé ou eu une
réponse sur irc de mettre à jour ses posts sur la ml. Et de partager
dans le même temps la solution wink Just a talk....

Hors ligne

#4 16-05-2009 22:06:14

Lior Gradstein
Membre
Inscription : 11-08-2010
Messages : 2

Re : Exécution multiple des signaux lorsqu'on les définie dans models.py ?

Tu as tout à fait raison :-) J'avais oublié de poster la réponse
(j'étais pressé de rentrer chez moi, on était vendredi soir :-)

Pour résumer ma situation, histoire que vous compreniez bien :

Si l'on fait un "signals.pre_save.connect(ma_methode, sender=MyModel)"
dans son models.py, dans la théorie il sera exécuté à chaque fois que
l'on fait un 'from models import MonModel', ce qui est assez courant
(dans admin.py, form.py, fields.py, etc).

Pour empêcher ça, les dev de Django ont mis un test dans
django/dispatch/dispatcher.py:
class Signal:
[...]
   def connect(...):
       [...]
       lookup_key = (_make_id(receiver), _make_id(sender))
       for r_key, _ in self.receivers:
            if r_key == lookup_key:
                break
[...]

En gros, on prend la signature du module qui est appelé et on la
compare à la liste des méthodes déjà stockées. Mon problème c'était
que à un endroit j'avais mis un 'from monapp.models import MonModele'
et dans un autre module 'from models import MonModele', ce qui donne
une signature différente...


Merci benoit !


2009/5/16 Benoit Chesneau <bchesneau _AT_ gmail.com>:
> Le 16 mai 2009 18:37, Stéphane Bunel <stephane+djangofr _AT_ bpf.st> a écrit :
>> Le vendredi 15 mai 2009 11:57:16, Lior Gradstein a écrit :
>>> Bonjour,
>>>
>>> J'attache une methode à un signal avec la commande
>>> "signals.pre_save.connect(ma_methode, sender=MonModele)", que j'inclue dans
>>> mon fichier models.py:
>>>
>>> def ma_methode(sender, instance, signal, *args, **kwargs):
>>>    print "Hello world"
>>>
>>> from django.db.models import signals
>>> signals.pre_save.connect(ma_methode, sender=MyModel)
>>>
>>>
>>> Mon problème: si je mets un print dans cette methode, je vois qu'elle est
>>> appelée plusieurs fois lors de la création de mon modele (soumission de mon
>>> formulaire), alors qu'il ne devrait y passer qu'une fois.
>>>
>>> La raison: j'ai mis ce signals.pre_save.connect() à la fin de mon models.py,
>>> ce qui fait qu'il est exécuté dès que dans un autre module je fais un "from
>>> models import MyModel" (par exemple dans mon form.py, ce que, je suppose,
>>> tout le monde fait). Pourtant, lorsque je regarde dans ce qui se fait dans
>>> les autres projets, le placement dans le models.py est recommandé.
>>>
>>> Alors comment est-ce possible ? Je ne souhaite pas que ma méthode soit
>>> appelée plusieurs fois !
>>
>> J'ai rencontré ce cas. Il est en fait très logique car le dispatcher est
>> sollicité à chaque import et enregistre donc plusieurs fois les signaux.
>>
>> Pour éviter d'enregistrer plusieurs fois le même signal il suffit de lui donner
>> un identifiant au moment de l'enregistrer.
>>
>> Ainsi le dispatcher pourra alors se rendre compte, grâce à l'identifiant, si
>> l'on tente d'enregistrer plusieurs fois le même signale.
>>
>> Exemple:
>>
>> signals.post_save.connect( person_post_save_callback,
>>    sender = Person,
>>    dispatch_uid = 'person_post_save_callback' )
>>
>> Je donne le nom de la méthode invoquée comme identifiant mais c'est un choix
>> personnel et arbitraire.
>>
>> Stéphane Bunel.
>> (...)
>>
>> _______________________________________________
>> django mailing list
>> django _AT_ lists.afpy.org
>> http://lists.afpy.org/mailman/listinfo/django
>>
>
> rien de logique à cela si on on considère que id donne un identifiant
> unique. Ceci dit comme vu sur irc models.mafonction ne renvoie pas le
> même id que mafonction seul. D'ou le problème et la nécessité quand on
> est pas homogène dans son code d'utiliser dispatch_uid.
>
> Dans tous les cas il serait bien quand une personne a trouvé ou eu une
> réponse sur irc de mettre à jour ses posts sur la ml. Et de partager
> dans le même temps la solution wink Just a talk....
> _______________________________________________
> django mailing list
> django _AT_ lists.afpy.org
> http://lists.afpy.org/mailman/listinfo/django
>

Hors ligne

#5 16-05-2009 22:26:43

Stephane Bunel
Membre
Inscription : 11-08-2010
Messages : 11

Re : Exécution multiple des signaux lorsqu'on les définie dans models.py ?

Le samedi 16 mai 2009 22:00:07, Benoit Chesneau a écrit :
> Le 16 mai 2009 18:37, Stéphane Bunel <stephane+djangofr _AT_ bpf.st> a écrit :
> > Le vendredi 15 mai 2009 11:57:16, Lior Gradstein a écrit :
> >> Bonjour,
> >>
> >> J'attache une methode à un signal avec la commande
> >> "signals.pre_save.connect(ma_methode, sender=MonModele)", que j'inclue
dans
> >> mon fichier models.py:
> >>
> >> def ma_methode(sender, instance, signal, *args, **kwargs):
> >>    print "Hello world"
> >>
> >> from django.db.models import signals
> >> signals.pre_save.connect(ma_methode, sender=MyModel)
> >>
> >>
> >> Mon problème: si je mets un print dans cette methode, je vois qu'elle est
> >> appelée plusieurs fois lors de la création de mon modele (soumission de
mon
> >> formulaire), alors qu'il ne devrait y passer qu'une fois.
> >>
> >> La raison: j'ai mis ce signals.pre_save.connect() à la fin de mon
models.py,
> >> ce qui fait qu'il est exécuté dès que dans un autre module je fais un
"from
> >> models import MyModel" (par exemple dans mon form.py, ce que, je suppose,
> >> tout le monde fait). Pourtant, lorsque je regarde dans ce qui se fait
dans
> >> les autres projets, le placement dans le models.py est recommandé.
> >>
> >> Alors comment est-ce possible ? Je ne souhaite pas que ma méthode soit
> >> appelée plusieurs fois !
> >
> > J'ai rencontré ce cas. Il est en fait très logique car le dispatcher est
> > sollicité à chaque import et enregistre donc plusieurs fois les signaux.
> >
> > Pour éviter d'enregistrer plusieurs fois le même signal il suffit de lui
donner
> > un identifiant au moment de l'enregistrer.
> >
> > Ainsi le dispatcher pourra alors se rendre compte, grâce à l'identifiant,
si
> > l'on tente d'enregistrer plusieurs fois le même signale.
> >
> > Exemple:
> >
> > signals.post_save.connect( person_post_save_callback,
> >    sender = Person,
> >    dispatch_uid = 'person_post_save_callback' )
> >
> > Je donne le nom de la méthode invoquée comme identifiant mais c'est un
choix
> > personnel et arbitraire.
> >
> > Stéphane Bunel.
> > (...)
> >
> > _______________________________________________
> > django mailing list
> > django _AT_ lists.afpy.org
> > http://lists.afpy.org/mailman/listinfo/django
> >
>
> rien de logique à cela si on on considère que id donne un identifiant
> unique. Ceci dit comme vu sur irc models.mafonction ne renvoie pas le
> même id que mafonction seul. D'ou le problème et la nécessité quand on
> est pas homogène dans son code d'utiliser dispatch_uid.

De quoi parlez-vous à propos d'IRC ?!

> Dans tous les cas il serait bien quand une personne a trouvé ou eu une
> réponse sur irc de mettre à jour ses posts sur la ml. Et de partager
> dans le même temps la solution wink Just a talk....

...BIP... ??? Vraiment, désolé, je ne sais pas de quoi vous voulez parler à
propos d'IRC et le reste... Mais avec ce genre de commentaire ne vous étonnez
pas que le partage soit aussi faible sur les ML française.

Stéphane Bunel.
(...)

Hors ligne

  • Accueil
  • » Django-fr
  • » Exécution multiple des signaux lorsqu'on les définie dans models.py ?

Pied de page des forums