2011-01-27 13 views
5

Mi chiedo se sia possibile sopprimere selettivamente un segnale Django (come post_save o post_init) sulla creazione dell'oggetto o, in alternativa, inviarlo determinati parametri.È possibile sopprimere selettivamente un segnale post_save (o altro) in Django?

Quello che ho è un oggetto User, che può essere creato in molti modi e luoghi diversi nel mio codice. Quindi per assegnare automaticamente un oggetto personalizzato Profile a ogni User, io uso il segnale post_save. Tuttavia, in un caso specifico, vi sono informazioni aggiuntive che desidero associare all'oggetto Profile creato. Passarlo come argomento al segnale post_save sarebbe ottimo, ma non sembra possibile.

L'altra opzione è quella di creare manualmente l'oggetto Profile, ma poi devo che dopo la User è salvato, altrimenti la Profile non può essere vincolato a un'istanza User. Salvando l'istanza User, tuttavia, viene creato un altro Profile creato tramite la funzione chiamata dal segnale.

E non riesco a ottenere l'oggetto appena creato Profile, dal momento che si verifica un errore 'Profile' object is unsubscriptable. Qualche consiglio?

Aggiornamento:

Ecco un esempio di una possibile situazione:

def createUserProfile(sender, instance, created, **kwargs): 
if created: 
    profile, created = Profile.objects.get_or_create(user=instance) 
    if extra_param: 
     profile.extra_param = extra_param 
    profile.save() 

post_save.connect(createUserProfile, sender=User) 

def signup(request): 
    ... 
    extra_param = 'param' 
    user.save() 

Come faccio ad avere la variabile extra_param nel metodo signup al metodo createUserProfile, dove deve essere memorizzato come parte dell'oggetto Profile?

+1

+1. Mi piacerebbe sapere la risposta a questo. – PeanutButterJelly

risposta

2

Perché questo non funziona per te?

user = User(...) 
user.save() 
# profile has been created transparently by post_save event 
profile = user.profile 
profile.extra_stuff = '...' 
profile.save() 

Se siete ossessionati con i parametri di passaggio per eventi, possibile, ma il male:

user = User() 
user._evil_extra_args = { ... } 
user.save() 

In event: 
extra_args = getattr(user, '_evil_extra_args', False) 

È male perché le persone che leggeranno il vostro codice non avrà idea di cosa diavolo quei _evil_extra_args è per e Come funziona.

+3

Alla fine ho optato per l'opzione male, dato che la prima dà una sorta di errore di concorrenza (l'oggetto db è ancora bloccato dall'evento 'save()' quando provo ad accedere al profilo). –

0

Il ritardo post_save non è possibile (a meno che non si desideri entirely disconnect it), ma non è nemmeno necessario. Passare un parametro al profilo non è affatto un problema:

class UserProfile(models.Model): 
    user = models.ForeignKey(User) 
    other = models.SomeField() 

def create_user_profile(sender, instance, created, other_param=None, **kwargs): 
    if created: 
     profile, created = UserProfile.objects.get_or_create(user=instance) 
     profile.other(other_param) # or whatever 
     profile.save() 

post_save.connect(create_user_profile, sender=User, other_param=p) 
+0

Cosa succede se voglio inviare quel parametro solo in un caso, e il 'post_save.connect' è definito da qualche altra parte rispetto alla funzione che crea l'oggetto' Utente' stesso? Come funzionerebbe? –

+0

basta dare un valore predefinito ... (risposta modificata) –

+0

Penso che uno di noi stia fraintendendo l'altro, quindi ho aggiunto un esempio alla mia domanda che, si spera, chiarirà il problema. –

Problemi correlati