2012-04-24 12 views
19

Estoy conectando una señal post_save personalizada y noté que parece que no puedo encontrar una manera fácil de pasar un conjunto de kwargs.Cómo pasar kwargs de guardar a la señal de post_save

Durante el mismo guardar (dentro de un formulario personalizado)

def save(self, commit=True): 
    user = super(CustomFormThing, self).save(commit=False) 
    #set some other attrs on user here ... 
    if commit: 
     user.save() 

    return user 

A continuación, dentro de mi gancho post_save personalizada Tengo el siguiente (pero nunca obtener ningún kwargs)

@receiver(post_save, sender=User) 
def create_profile(sender, instance, created, **kwargs): 
    some_id = kwargs.get('some', None) 
    other_id = kwargs.get('other', None) 

    if created: 
     #do something with the kwargs above... 

¿Cómo podría yo pasar kwargs desde el guardar hasta el evento post_save?

+0

Estoy interesado en pasar otros argumentos (atributos no usuario) que vivirían en un perfil de usuario (aislado desde el propio usuario Django). El mensaje de guardar como un gran lugar para lograr esto ... excepto que no puedo obtener ninguna variable externa. Voy a intentar tu sugerencia y volveré a publicar si eso funciona (aunque me gustaría aprovechar los ** kwargs en la señal de post_save en sí) –

+0

No creo que la señal sea una buena idea aquí. Las señales son buenas cuando se crean objetos en diferentes partes del código (incluso fuera de la aplicación). Pero en su caso, la señal es inútil si el objeto se crea fuera del formulario. Así que creo que la forma más racional es crear 'Usuario' y perfil directamente en el guardado del formulario. Fácil de implementar, fácil de entender el código más tarde. – DrTyrsa

+0

Creo que la mayoría de la gente (vale, tal vez solo yo :) hago la creación del perfil de usuario y me preocupa el método save() anulado, no en post_save(). Pero sus requisitos pueden ser diferentes. En cualquier caso, también podría llamar a 'instance.get_profile()' en post_save, si el perfil ya se había creado, y si eso ayudaría. – alan

Respuesta

28

Las señales incorporadas son enviadas por Django, por lo que no puede controlar sus kwargs.

Puede:

  1. Definir y enviar sus propias señales.
  2. Almacenar información adicional en la instancia del modelo. Al igual que este

    def save(self, commit=True): 
        user = super(CustomFormThing, self).save(commit=False) 
        #set some other attrs on user here ... 
        user._some = 'some' 
        user._other = 'other' 
        if commit: 
         user.save() 
    
        return user 
    
    @receiver(post_save, sender=User) 
    def create_profile(sender, instance, created, **kwargs): 
        some_id = getattr(instance, '_some', None) 
        other_id = getattr(instance, '_other', None) 
    
        if created: 
         #do something with the kwargs above... 
    
+0

+1 mejor respuesta que la mía. Debería haber pensado en usar getattr(). También es bueno confirmar que puedes pasar atributos adicionales usando 'instance'. – alan

+0

¿Qué hay de llamar 'self.save_m2m()' después de 'user.save()'? ¿No es eso necesario? – thnee

2

No creo que haya una manera de pasar un conjunto separado de kwargs. ¿Qué argumentos desea además de los atributos User? Puede acceder a los atributos User en el controlador de señal en el argumento instance. instance será el objeto User que acaba de guardarse.

Si hay otras cosas que quiere transmitir, supongo que se podría tratar de usar el arg instance como una paloma:

def save(self, commit=True): 
    user = super(CustomFormThing, self).save(commit=False) 
    user.foo = 'bar' 
    if commit: 
     user.save() 
    ... 

A continuación, en el controlador:

def create_profile(sender, instance, created, **kwargs): 
    myfoo = instance.foo 

Pero lo anterior no se ha probado, y no estoy seguro de que funcione.

Cuestiones relacionadas