2013-04-09 12 views
6

Po dodaniu nowego rekordu do tabeli, muszę wykonać instrukcję SQL w zewnętrznej bazie danych. To zapytanie obejmuje użycie ManyToManyField. Więc po prostu podłączyć funkcję tak:Funkcja ManyToManyField jest pusta w funkcji post_save()

post_save.connect(post_save_mymodel, sender=MyModel) 

A w moim post_save_mymodel funkcji(), tutaj jest to, co robię:

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

Ale szkoda, instance.my_m2mfield.all() jest zawsze puste! Chociaż powinny zawierać pewne elementy! Starałem się uzyskać nowy element wykonując

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

ale to niczego nie zmienia, wciąż mam ten sam problem ...

WNY pomocy/porady?

Odpowiedz

6

Dzieje się tak, ponieważ najpierw zapisujesz swoją instancję, a następnie dodajesz do niej relacje m2m. W ten sposób pola ManyToMany działają w modelach danych Django. Django musi znać identyfikator przedmiotów, które powinny być powiązane z relacjami m2m.

myślę, że Twój kod wygląda następująco:

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

trzeba podłączyć do obsługi sygnału django.db.models.signals.m2m_changed. Zobacz the docs. Na przykład:

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

To rozwiązanie działa idealnie. Zakładam więc, że konieczne jest sprecyzowanie atrybutu, aby sygnał był wywoływany we właściwym czasie? Dzięki i tak. – Deneuve

+0

W szczegółach jest diabeł. Procedura obsługi post_save_model nie jest wywoływana z ustawieniem akcji na "post_add", jeśli zawartość pola m2m zostanie wyczyszczona. Możesz chcieć wykryć to wydarzenie. Istnieje akcja "post_clear", ale, niestety, Django wydaje się usuwać pola m2m przed ich zmianą, więc zdarzenie "post_clear" jest generowane podczas zmian w polu m2m, jak również po jego wyczyszczeniu. – nmgeek

+0

@Deneuve, Co "precyzyjne atrybut "znaczy? – nmgeek