(Django 1.1) Tengo un modelo de proyecto que realiza un seguimiento de sus miembros utilizando un campo m2m. Se ve así:Django - ¿Cómo guardar datos m2m a través de la señal 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) ...
Cuando se crea el proyecto, el seleccionado sales_rep
, sales_mgr
, project_mgr
, etc User
s se añaden a los miembros para que sea más fácil hacer un seguimiento de permisos de proyecto. Este enfoque ha funcionado muy bien hasta ahora.
El problema que estoy tratando ahora es cómo actualizar la membresía del proyecto cuando uno de los campos User
FK se actualiza a través del administrador. He intentado varias soluciones a este problema, pero el enfoque más limpio que parecía ser una señal de post_save
como la siguiente:
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)
Sin embargo, el Project
todavía tiene los mismos miembros, incluso si cambio de uno de los campos a través de la ¡administración! He tenido éxito actualizando los campos m2m de miembros usando mis propios puntos de vista en otros proyectos, pero nunca tuve que hacerlo jugar bien con el administrador también.
¿Hay otro enfoque que debo tomar aparte de una señal post_save para actualizar la membresía? ¡Gracias de antemano por tu ayuda!
ACTUALIZACIÓN:
Solo para aclarar, la señal post_save funciona correctamente cuando guardo mi propia forma en el extremo delantero (miembros antiguos se eliminan, y los nuevos se añaden). Sin embargo, la señal post_save NO funciona correctamente cuando guardo el proyecto a través del administrador (los miembros permanecen igual).
creo diagnóstico de Peter Rowell es correcto en esta situación. Si elimino el campo "miembros" del formulario de administrador, la señal post_save funciona correctamente. Cuando se incluye el campo, guarda los miembros antiguos según los valores presentes en el formulario en el momento del guardado. Independientemente de los cambios que realice en el campo m2m de los miembros cuando se guarda el proyecto (ya sea una señal o un método de guardado personalizado), siempre será sobrescrito por los miembros que estaban presentes en el formulario antes del guardado. Gracias por señalar eso!
No sé si este es su problema, pero tengo el presentimiento de que puede que esté ejecutando en un artefacto de la forma en que el código de formas actualiza la información de m2m. Básicamente, primero guardan el objeto principal, luego establecen los valores de m2m borrándolos primero y luego configurándolos en función de los valores presentes * en el formulario *. Esto sucede * después de * guardar() en el objeto principal, por lo que cualquier cosa que haga en guardar() o en función de la señal 'post_save' se hace primero, y luego * deshacer *. Esto está en 'django.forms.models.save_instance()'. Sería bueno si hubiera una señal 'after_form_save'. –
¡Gracias, Peter! Creo que su diagnóstico es correcto. Actualicé mi publicación original para incluir esta información. –
Peter tiene razón. Tuve el mismo problema y encontré una solución, pero no es una buena señal de 'after_form_save': http://stackoverflow.com/questions/3652585/simple-django-form-model-save-question –