Aggiorna solo campi specifici in models.Model


92

Ho un modello

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

e ora voglio aggiornare solo il activecampo. Quindi faccio questo:

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

Ora ricevo un errore IntegrityError: PRIMARY KEY must be unique.

Ho ragione con questo metodo per aggiornare?

Risposte:


187

Per aggiornare un sottoinsieme di campi, puoi utilizzare update_fields:

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

L' update_fieldsargomento è stato aggiunto in Django 1.5. Nelle versioni precedenti, potresti update()invece utilizzare il metodo:

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

17

Di solito, il modo corretto di aggiornare determinati campi in una o più istanze del modello è utilizzare il update()metodo sul rispettivo set di query. Quindi fai qualcosa del genere:

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

In questo modo, non è più necessario chiamare save()il tuo modello perché viene salvato automaticamente. Inoltre, il update()metodo restituisce il numero di istanze di sondaggio interessate dal tuo aggiornamento.


2
Grazie. L'ho provato con .getinvece di .filtere questo non funziona. Ma con il filtro funziona bene. Sai cosa c'è che non va nel mio codice qui sopra?
Utente registrato il

Il tuo problema potrebbe essere correlato a question_id. Da dove viene questo valore? E quale linea esatta solleva il IntegrityError?
pemistahl

question_idproviene da URL (?P<question_id>\d+). La mia colpa è stata che sul server funzionante django 1.4 è installato e il mio codice è 1.5. Ma con il tuo codice funziona bene.
Utente registrato il

2
@RegisteredUser, sembra che non ci sia alcun metodo di "aggiornamento" sugli oggetti, ma solo sui set di query. Quando usi .filter (), ottieni un set di query (che contiene zero o più oggetti). Quando usi .get () ottieni un singolo oggetto.
mgojohn

Per impostazione predefinita, la chiamata save()(soluzione @Alasdair) è una soluzione più sicura, perché questo metodo può attivare cose come la convalida o qualsiasi codice personalizzato, rispetto a quanto update()non lo fa.
David D.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.