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.