Django-fr

Forum

#1 07-06-2009 00:51:52

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

Detection de modification d'une relation ManyToMany

Bonjour,

Partant de l'extrait suivant d'un model.py:

class Group( models.Model ):
    ...
    name            = models.CharField( ...)
    ...

class Account( models.Model ):
    ...
    groups          = models.ManyToManyField( Group )
    ...

et du GroupAdmin / AccountAdmin qui vont avec. L'interface d'administration
affiche sous forme d'une liste, pour chaque Account, le nom de tout les
groupes que l'on peut sélectionner (ou dé-sélectionner). Ok.

* Pour traitement, j'ai posé un signal (pre_save) sur Account pour suivre
   la modification des attributs.

* Pour déterminer quels sont les attributs modifiés, je requête en base
   l'état précédent de l'instance - puisque les nouvelles données ne sont
   pas encore enregistrées (pre_save) - et compare les deux résultats.

* Je souhaite savoir si la "valeur de l'attribut" groups a changée.
   L'attribut groups étant particulier (table de liaison entre Account
   et Group) j'ai pensé:

1. A poser un signal sur la relation créer par le type ManyToManyFileld.
   Je n'ai rien trouvé de ce coté. Il y a bien une proposition de patch
   [1], datant de plus de deux ans, qui répondrait parfaitement à mon
   souhait, mais il n'est pas intégré à ma version 1.02 de Django.

2. A récupérer la liste des groupes associé à l'instance ayant émis le signal.
   Mais je remarque que instance.groups.all() et Account.objects.get( pk
   = instance.id ).groups.all() renvoie toujours un résultat identique.

3. A mémoriser l'état des groupes associées à une instance d'Account
   (gruik) dans un dictionnaire. Mais, la encore, le retour de
   instance.groups.all() est identique à l'état mémorisé. Ce qui signifie
   que la relation portée par l'attribut groups est mise à jour APRES
   l'enregistrement en base de l'instance Account.

4. A créer un modèle intermédiaire, l'indiquer par l'option
   ManyToManyField.through puis poser un signal sur le modèle intermédiaire.
   Cela devrait fonctionner mais les contraintes sont trop importantes [2].

Ais-je loupé la bonne solution ou est-ce que Django ne permet pas de façon
élégante de savoir comment une relation ManyToMany a été modifiée (ce qui me
surprendrais) ?


Stéphane Bunel.

[1] http://code.djangoproject.com/ticket/5390
[2] http://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-
manytomany
  - "Unlike normal many-to-many fields, you can't use add, create, or
assignment (i.e., beatles.members = [...]) to create relationships"

Hors ligne

#2 07-06-2009 23:39:52

David Larlet
Membre
Inscription : 11-08-2010
Messages : 102

Re : Detection de modification d'une relation ManyToMany

Hello,

Le 7 juin 09 à 01:51, Stéphane Bunel a écrit :
> 1. A poser un signal sur la relation créer par le type 
> ManyToManyFileld.
>   Je n'ai rien trouvé de ce coté. Il y a bien une proposition de patch
>   [1], datant de plus de deux ans, qui répondrait parfaitement à mon
>   souhait, mais il n'est pas intégré à ma version 1.02 de Django.
> [1] http://code.djangoproject.com/ticket/5390

Tu es sûr que cette solution ne fonctionne pas (ou n'est pas 
adaptable) ?
xav sur irc l'utilise avec succès et le dernier patch n'a que 6 mois ;-)

Bonne soirée,
David

Hors ligne

#3 08-06-2009 20:05:42

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

Re : Detection de modification d'une relation ManyToMany

Le lundi 08 juin 2009 00:39:52, David Larlet a écrit :
> Hello,
>
> Le 7 juin 09 à 01:51, Stéphane Bunel a écrit :
> > 1. A poser un signal sur la relation créer par le type 
> > ManyToManyFileld.
> >   Je n'ai rien trouvé de ce coté. Il y a bien une proposition de patch
> >   [1], datant de plus de deux ans, qui répondrait parfaitement à mon
> >   souhait, mais il n'est pas intégré à ma version 1.02 de Django.
> > [1] http://code.djangoproject.com/ticket/5390
>
> Tu es sûr que cette solution ne fonctionne pas (ou n'est pas 
> adaptable) ?
> xav sur irc l'utilise avec succès et le dernier patch n'a que 6 mois ;-)

Oui, certain. J'ai vérifié le contenu du fichier django/db/models/signals.py:
il ne contient pas la ligne (magique) m2m_changed = Signal(...). Ca m'ennuie
terriblement de patcher, car à la prochain upgrade du package on risque
d'avoir oublié cette exception.

> Bonne soirée,

Merci,
de même.

Stéphane Bunel.

Hors ligne

Pied de page des forums