Wählen Sie den Datenbankeintrag aus und aktualisieren Sie ihn mit einem einzigen Abfragesatz

139

Wie führe ich eine updateund select-Anweisung auf demselben aus, querysetanstatt zwei Abfragen ausführen zu müssen: - eine zum Auswählen des Objekts - und eine zum Aktualisieren des Objekts

Das Äquivalent in SQL wäre etwa:

update my_table set field_1 = 'some value' where pk_field = some_value
John
quelle

Antworten:

266

Verwenden Sie die queryset Objektmethode :update

MyModel.objects.filter(pk=some_value).update(field1='some value')
Daniel Roseman
quelle
94
Nur eine faire Warnung ... Wenn Sie diese updateMethode verwenden, werden alle an dieses Modell oder andere "Code-Inhalte" angehängten Signale nicht gegen die Objekte ausgeführt. Nur ein
Hinweis
@ DMactheDestroyer Alter, danke für diese wertvollen Informationen. Sollten wir dann die ältere Art der Aktualisierung verwenden? (dh) bekommen und sparen?
@Learning gut Alter, es hängt alles von Ihrem Szenario ab. Die updateMethode eignet sich hervorragend für Massenaktualisierungen, sollte jedoch eine Warnung in Ihrem Kopf
auslösen,
3
Ist es möglich, in der Update-Funktion auf die aktuelle Modellinstanz zuzugreifen? wieMyModel.objects.filter(pk=some_value).update(field1=self.data)
Dipak
8
@DipakChandranP Sie sollten eine neue Frage stellen, anstatt eine sechsjährige zu kommentieren. Aber F () - Ausdrücke wollen wahrscheinlich, dass Sie wollen.
Daniel Roseman
70

Django-Datenbankobjekte verwenden dieselbe save () -Methode zum Erstellen und Ändern von Objekten.

obj = Product.objects.get(pk=pk)
obj.name = "some_new_value"
obj.save()

Wie Django UPDATE vs. INSERT kennt
Wenn das Primärschlüsselattribut des Objekts auf einen Wert festgelegt ist, der True ergibt (dh einen anderen Wert als None oder die leere Zeichenfolge), führt Django ein UPDATE aus. Wenn das Primärschlüsselattribut des Objekts nicht festgelegt ist oder wenn das UPDATE nichts aktualisiert hat, führt Django ein INSERT aus.

Ref.: Https://docs.djangoproject.com/de/1.9/ref/models/instances/

Windschatten
quelle
17

Diese Antwort vergleicht die beiden oben genannten Ansätze. Wenn Sie viele Objekte in einer einzigen Zeile aktualisieren möchten, gehen Sie wie folgt vor:

# Approach 1
MyModel.objects.filter(field1='Computer').update(field2='cool')

Andernfalls müssten Sie den Abfragesatz durchlaufen und einzelne Objekte aktualisieren:

#Approach 2    
objects = MyModel.objects.filter(field1='Computer')
for obj in objects:
    obj.field2 = 'cool'
    obj.save()
  1. Ansatz 1 ist schneller, da nur eine Datenbankabfrage durchgeführt wird, im Vergleich zu Ansatz 2, bei dem 'n + 1'-Datenbankabfragen durchgeführt werden. (Für n Elemente im Abfragesatz)

  2. Der erste Ansatz führt eine Datenbankabfrage durch, dh UPDATE, der zweite zwei: SELECT und dann UPDATE.

  3. Der Nachteil ist, dass, vorausgesetzt, Sie haben Auslöser wie Aktualisierungen updated_onoder ähnliche verwandte Felder, diese bei der direkten Aktualisierung, dh bei Ansatz 1, nicht ausgelöst werden.

  4. Ansatz 1 wird in einem Abfragesatz verwendet, sodass es möglich ist, mehrere Objekte gleichzeitig zu aktualisieren, nicht im Fall von Ansatz 2.

Pransh Tiwari
quelle
Zu 1. - Ich denke, das Abfrageergebnis wird beim ersten Aufruf der Abfrage zwischengespeichert, daher gibt es tatsächlich immer noch nur einen Aufruf an die DB.
user2340939
2

Nur in einem Fall serializerkönnen Sie auf sehr einfache Weise aktualisieren!

my_model_serializer = MyModelSerializer(
    instance=my_model, data=validated_data)
if my_model_serializer.is_valid():

    my_model_serializer.save()

nur in einem Fall in formDingen!

instance = get_object_or_404(MyModel, id=id)
form = MyForm(request.POST or None, instance=instance)
if form.is_valid():
    form.save()
Jamil Noyda
quelle
Ich denke, Serializer stammen von Djanog Rest Framework und nicht von Django.
Code-Apprentice
1
Ja, aber Django formist von Django Proper.
Jamil Noyda