2013-04-09 14 views
6

Quando un nuovo record viene aggiunto a una tabella, devo eseguire un'istruzione SQL su un database esterno. Questa query include l'uso di ManyToManyField. Così ho appena collegato la funzione in questo modo:ManyToManyField è vuoto nella funzione post_save()

post_save.connect(post_save_mymodel, sender=MyModel) 

E nella mia funzione post_save_mymodel(), qui è quello che faccio:

def post_save_mymodel(sender, instance, created, *args, **kwargs): 
    if created: 
     for e in instance.my_m2mfield.all(): 
      # Query including "e". 

Ma, troppo male, instance.my_m2mfield.all() è sempre vuoto! Anche se dovrebbero contenere alcuni elementi! Ho cercato di ottenere il nuovo elemento facendo

new_element = MyModel.objects.get(pk=instance.pk) 

ma non cambia nulla, ho ancora lo stesso problema ...

WNY aiuto/consigli?

risposta

6

Questo perché si salva prima l'istanza e successivamente si aggiungono le relazioni m2m. Ecco come funzionano ManyToMany nei modelli di dati Django. Django ha bisogno di conoscere l'ID degli elementi che dovrebbero essere collegati alle relazioni m2m.

Penso che il codice simile a questo:

instance = MyModel.objects.create(some_field=some_value) # post save signal triggered here 
instance.my_m2mfield = my_set_of_m2m_models 

è necessario collegare il vostro gestore per il segnale django.db.models.signals.m2m_changed. Vedi the docs. Ad esempio:

def post_save_mymodel(sender, instance, action, reverse, *args, **kwargs): 
    if action == 'post_add' and not reverse: 
     for e in instance.my_m2mfield.all(): 
      # Query including "e" 
m2m_changed.connect(post_save_mymodel, sender=MyModel.my_m2mfield.through) 
+0

Questa soluzione funziona perfettamente. Quindi presumo sia necessario precisare l'attributo, perché il segnale venga chiamato al momento giusto? Grazie comunque. – Deneuve

+0

C'è un diavolo nei dettagli. Il gestore post_save_model non viene chiamato con l'azione impostata su 'post_add' se i contenuti del campo m2m vengono cancellati. Potresti voler rilevare quell'evento. Esiste un'azione "post_clear" ma, sfortunatamente, Django sembra cancellare i campi m2m prima di cambiarli in modo che l'evento "post_clear" venga generato durante le modifiche al campo m2m e quando viene cancellato. – nmgeek

+0

@Deneuve, cosa significa "preciso" l'attributo "significa? – nmgeek

Problemi correlati