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

Antworten:


266

Verwenden Sie die queryset Objektmethode :update

MyModel.objects.filter(pk=some_value).update(field1='some value')

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/


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.


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()

Ich denke, Serializer stammen von Djanog Rest Framework und nicht von Django.
Code-Apprentice

1
Ja, aber Django formist von Django Proper.
Jamil Noyda
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.