2010-11-05 13 views
15

¿Cómo puedo pasar un dict que contiene campos para actualizar un modelo de Django? Esto no es para crear un objeto, sino para actualizarlo.Actualizar modelo django a través de kwargs

ejemplo:

obj = Object.objects.create(index=id, **fields) 

Respuesta

25

Mientras la PK es el mismo, se sobrescribirá la fila existente.

obj = Object(index=id, **fields) 
obj.save() 
+0

¿Quiere decir que va a crear si en la base de datos no hay un campo con índice y actualizar si hay un campo con ese índice? Entonces, ¿podemos llamarlo update_or_create? – Pol

+0

Eso es correcto. –

+0

Ohh hombre !!! Ya terminé mi método de create_or_update ... Cose encontré artikle que no hay método para crear o actualizar en django. Hay artikle: http://blog.roseman.org.uk/2010/03/9/easy- crear-o-actualizar/¿es un artículo incorrecto? – Pol

11
def update_object(obj, **kwargs): 
    for k, v in kwargs.items(): 
     setattr(obj, k, v) 
    obj.save() 
+1

Esto puede no ser lo que quería OP ya que todos los campos se escriben en la base de datos; no solo los que están en 'kwargs', por lo que es posible que estén peleando. 1.5 introduce un argumento 'update_fields' en' model.save', aunque luego tendrías que repetir los nombres de los campos. – ded7

8

Usted puede obtener un conjunto de consultas de un objeto, y luego actualizar esta:

model = Model.objects.filter(pk=pk) 
model.update(**kwargs) 

esto no va a llamar al método .save() en el objeto, sin embargo. Sin embargo, creo que solo hará una consulta de base de datos.

Tenga en cuenta que si no filtró a un objeto (es decir, la consulta obtuvo varios objetos: por ejemplo, si no estuviera consultando PK), los actualizaría todos. Si se filtra a ninguno, entonces no se escribirá nada en la base de datos.

Habiendo dicho eso, no estaba al tanto de la solución de Ignacio. Me gusta bastante.

+0

Si logras obtener múltiples registros mientras filtras en el PK, entonces tienes ... problemas mayores. Filtrar a ninguno no es un problema, ya que es válido emitir una consulta 'UPDATE' que no coincide con ningún registro. –

+0

Sí, quise decir si no consultaste sobre PK, sino sobre otra cosa que se suponía que era única. –

3

Si usted sabe que quiere para crearlo:

Book.objects.create(**fields) 

Asumiendo que requiere para comprobar si hay una instancia existente, se puede encontrar con get o crear:

instance, created = Book.objects.get_or_create(slug=slug, defaults=fields) 
if not created: 
    for attr, value in fields.iteritems(): 
     setattr(instance, attr, value) 
    instance.save() 

Como se mencionó en otra Respuesta, también puede usar la función update en el administrador de conjuntos de consultas, pero creo que no enviará ninguna señal (lo que puede no importarle si no los está usando). Sin embargo, es probable que no se debe utilizar para alterar un solo objeto:

Book.objects.filter(id=id).update(**fields) 
+0

+1 porque usa 'defaults' y' setattr' para asegurarse de que el contenido de los campos se aplique al objeto sin perder ningún atributo adicional que ya se haya establecido en una instancia existente – rhunwicks

3

Esta pregunta es un poco viejo, pero sólo para ponerla al día con los desarrollos recientes de Django - desde 1.7 ha habido un método update_or_create en querysets que funciona de manera similar a get_or_create.

En este caso se podría utilizar como:

obj, created = Object.objects.update_or_create(index=id, defaults=fields) 
Cuestiones relacionadas