(Django 1.1) Ho un modello di progetto che tiene traccia dei suoi membri utilizzando un campo m2m. Ecco come si presenta:Django - Come salvare i dati m2m tramite segnale post_save?
class Project(models.Model):
members = models.ManyToManyField(User)
sales_rep = models.ForeignKey(User)
sales_mgr = models.ForeignKey(User)
project_mgr = models.ForeignKey(User)
... (more FK user fields) ...
Quando viene creato il progetto, selezionato sales_rep
, sales_mgr
, project_mgr
, ecc User
s vengono aggiunti ai membri per rendere più facile per tenere traccia dei permessi di progetto. Questo approccio ha funzionato molto bene finora.
Il problema che sto trattando ora è come aggiornare l'appartenenza al progetto quando uno dei campi FK User
viene aggiornato tramite l'amministratore. Ho provato varie soluzioni a questo problema, ma l'approccio più pulito sembrava essere un segnale post_save
come la seguente:
def update_members(instance, created, **kwargs):
"""
Signal to update project members
"""
if not created: #Created projects are handled differently
instance.members.clear()
members_list = []
if instance.sales_rep:
members_list.append(instance.sales_rep)
if instance.sales_mgr:
members_list.append(instance.sales_mgr)
if instance.project_mgr:
members_list.append(instance.project_mgr)
for m in members_list:
instance.members.add(m)
signals.post_save.connect(update_members, sender=Project)
Tuttavia, il Project
ha ancora gli stessi membri, anche se cambio uno dei campi attraverso il Admin! Ho avuto successo nell'aggiornare i campi m2m dei membri usando le mie opinioni in altri progetti, ma non ho mai dovuto farlo funzionare bene con l'amministratore.
C'è un altro approccio che dovrei prendere oltre a un segnale post_save per aggiornare l'abbonamento? Grazie in anticipo per il vostro aiuto!
UPDATE:
solo per chiarire, il segnale post_save funziona correttamente quando salvo la mia propria forma nel front-end (vecchi membri vengono rimossi, e quelli nuovi aggiunti). Tuttavia, il segnale post_save NON funziona correttamente quando salvi il progetto tramite l'admin (i membri rimangono uguali).
Penso che la diagnosi di Peter Rowell sia corretta in questa situazione. Se rimuovo il campo "membri" dal modulo di amministrazione, il segnale post_save funziona correttamente. Quando il campo è incluso, salva i vecchi membri in base ai valori presenti nel modulo al momento del salvataggio. Indipendentemente dalle modifiche apportate al campo m2m dei membri quando il progetto viene salvato (sia esso un segnale o un metodo di salvataggio personalizzato), verrà sempre sovrascritto dai membri presenti nel modulo prima del salvataggio. Grazie per la segnalazione!
Non so se questo è il tuo problema, ma ho una sensazione viscerale che si può essere in esecuzione in un manufatto di come il codice di forme aggiorna informazioni m2m. Fondamentalmente prima salvano l'oggetto principale, quindi impostano i valori m2m prima cancellandoli tutti e quindi impostandoli in base ai valori presenti * nel modulo *. Questo accade * dopo * il save() sull'oggetto principale, quindi tutto ciò che fai in save() o basato sul segnale 'post_save' viene prima fatto, e quindi * annullato *. Questo è in 'django.forms.models.save_instance()'. Sarebbe bello se ci fosse un segnale 'after_form_save'. –
Grazie, Peter! Credo che la tua diagnosi sia corretta. Ho aggiornato il mio post originale per includere queste informazioni. –
Peter ha ragione. Ho avuto lo stesso problema e ho trovato una soluzione alternativa, ma non è un segnale "after_form_save": http://stackoverflow.com/questions/3652585/simple-django-form-model-save-question –