Aktualisieren Sie nur bestimmte Felder in einem models.Model

88

Ich habe ein Modell

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

und jetzt möchte ich nur das activeFeld aktualisieren . Also mache ich das:

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

Jetzt bekomme ich eine Fehlermeldung IntegrityError: PRIMARY KEY must be unique.

Bin ich mit dieser Methode zum Aktualisieren richtig?

registrierter Nutzer
quelle

Antworten:

178

Um eine Teilmenge von Feldern zu aktualisieren, können Sie Folgendes verwenden update_fields:

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

Das update_fieldsArgument wurde in Django 1.5 hinzugefügt. In früheren Versionen konnten Sie update()stattdessen die folgende Methode verwenden:

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

Normalerweise besteht die richtige Methode zum Aktualisieren bestimmter Felder in einer oder mehreren Modellinstanzen darin, die update()Methode auf dem jeweiligen Abfragesatz zu verwenden. Dann machst du so etwas:

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

Auf diese Weise müssen Sie save()Ihr Modell nicht mehr aufrufen, da es automatisch gespeichert wird. Außerdem gibt die update()Methode die Anzahl der Umfrageinstanzen zurück, die von Ihrem Update betroffen waren.

pemistahl
quelle
2
Vielen Dank. Ich habe es mit .getstatt versucht .filterund das funktioniert nicht. Aber mit Filter funktioniert es gut. Wissen Sie, was mit meinem obigen Code nicht stimmt?
Registrierter Benutzer
Ihr Problem könnte damit zusammenhängen question_id. Woher kommt dieser Wert? Und welche genaue Linie erhöht die IntegrityError?
Pemistahl
question_idkommt von URLs (?P<question_id>\d+). Mein Fehler war, dass auf dem funktionierenden Server Django 1.4 installiert ist und mein Code 1.5 ist. Aber mit Ihrem Code funktioniert es gut.
Registrierter Benutzer
2
@RegisteredUser, es sieht so aus, als gäbe es keine "Update" -Methode für Objekte, nur für Abfragesätze. Wenn Sie .filter () verwenden, erhalten Sie einen Abfragesatz (der null oder mehr Objekte enthält) zurück. Wenn Sie .get () verwenden, erhalten Sie ein einzelnes Objekt.
Mgojohn
Standardmäßig ist das Aufrufen save()(@ Laslasair-Lösung) eine sicherere Lösung, da diese Methode möglicherweise eine Validierung oder einen benutzerdefinierten Code auslöst update().
David D.