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.