Actualice solo campos específicos en un modelo.


92

Tengo un modelo

class Survey(models.Model):
    created_by = models.ForeignKey(User)
    question = models.CharField(max_length=150)
    active = models.NullBooleanField()
    def __unicode__(self):
        return self.question

y ahora quiero actualizar solo el activecampo. Entonces hago esto:

survey = get_object_or_404(Survey, created_by=request.user, pk=question_id)
survey.active = True
survey.save(["active"]) 

Ahora me sale un error IntegrityError: PRIMARY KEY must be unique.

¿Estoy en lo cierto con este método para actualizar?

Respuestas:


187

Para actualizar un subconjunto de campos, puede usar update_fields:

survey.save(update_fields=["active"]) 

El update_fieldsargumento se agregó en Django 1.5. En versiones anteriores, podría usar el update()método en su lugar:

Survey.objects.filter(pk=survey.pk).update(active=True)

17

Por lo general, la forma correcta de actualizar ciertos campos en una o más instancias del modelo es usar el update()método en el conjunto de consultas respectivo. Entonces haces algo como esto:

affected_surveys = Survey.objects.filter(
    # restrict your queryset by whatever fits you
    # ...
    ).update(active=True)

De esta manera, ya no necesita llamar save()a su modelo porque se guarda automáticamente. Además, el update()método devuelve el número de instancias de encuestas que se vieron afectadas por su actualización.


2
Gracias. Lo probé con en .getlugar de .filtery esto no funciona. Pero con el filtro funciona bien. ¿Sabes qué está mal con mi código anterior?
Usuario registrado

Su problema puede estar relacionado con question_id. ¿De dónde proviene este valor? ¿Y qué línea exacta eleva el IntegrityError?
pemistahl

question_idproviene de urls (?P<question_id>\d+). Mi culpa fue que en el servidor de trabajo django 1.4 está instalado y mi código es 1.5. Pero con tu código está funcionando bien.
Usuario registrado

2
@RegisteredUser, parece que no hay un método de "actualización" en los objetos, solo en los conjuntos de consultas. Cuando usa .filter (), obtiene un conjunto de consultas (que contiene cero o más objetos). Cuando usa .get () obtiene un solo objeto.
mgojohn

De forma predeterminada, llamar a save()(solución @Alasdair) es una solución más segura, porque este método puede desencadenar cosas como la validación o cualquier código personalizado que update()no.
David D.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.