Es gibt einige wichtige Unterschiede.
update
wird in einem Abfrage-Set verwendet, daher ist es möglich, mehrere Objekte gleichzeitig zu aktualisieren.
Wie @FallenAngel darauf hingewiesen, gibt es Unterschiede, wie benutzerdefinierten save()
Methode auslöst, aber es ist auch wichtig, im Auge zu behalten signals
und ModelManagers
. Ich habe eine kleine Test-App gebaut, um einige wertvolle Unterschiede zu zeigen. Ich benutze Python 2.7.5, Django == 1.7.7 und SQLite, beachten Sie, dass die endgültigen SQLs auf verschiedenen Versionen von Django und verschiedenen Datenbank-Engines variieren können.
Ok, hier ist der Beispielcode.
models.py
:
from __future__ import print_function
from django.db import models
from django.db.models import signals
from django.db.models.signals import pre_save, post_save
from django.dispatch import receiver
__author__ = 'sobolevn'
class CustomManager(models.Manager):
def get_queryset(self):
super_query = super(models.Manager, self).get_queryset()
print('Manager is called', super_query)
return super_query
class ExtraObject(models.Model):
name = models.CharField(max_length=30)
def __unicode__(self):
return self.name
class TestModel(models.Model):
name = models.CharField(max_length=30)
key = models.ForeignKey('ExtraObject')
many = models.ManyToManyField('ExtraObject', related_name='extras')
objects = CustomManager()
def save(self, *args, **kwargs):
print('save() is called.')
super(TestModel, self).save(*args, **kwargs)
def __unicode__(self):
# Never do such things (access by foreing key) in real life,
# because it hits the database.
return u'{} {} {}'.format(self.name, self.key.name, self.many.count())
@receiver(pre_save, sender=TestModel)
@receiver(post_save, sender=TestModel)
def reicever(*args, **kwargs):
print('signal dispatched')
views.py
:
def index(request):
if request and request.method == 'GET':
from models import ExtraObject, TestModel
# Create exmple data if table is empty:
if TestModel.objects.count() == 0:
for i in range(15):
extra = ExtraObject.objects.create(name=str(i))
test = TestModel.objects.create(key=extra, name='test_%d' % i)
test.many.add(test)
print test
to_edit = TestModel.objects.get(id=1)
to_edit.name = 'edited_test'
to_edit.key = ExtraObject.objects.create(name='new_for')
to_edit.save()
new_key = ExtraObject.objects.create(name='new_for_update')
to_update = TestModel.objects.filter(id=2).update(name='updated_name', key=new_key)
# return any kind of HttpResponse
, die in diesen SQL-Abfragen resuled:
# to_edit = TestModel.objects.get(id=1):
QUERY = u'SELECT "main_testmodel"."id", "main_testmodel"."name", "main_testmodel"."key_id"
FROM "main_testmodel"
WHERE "main_testmodel"."id" = %s LIMIT 21'
- PARAMS = (u'1',)
# to_edit.save():
QUERY = u'UPDATE "main_testmodel" SET "name" = %s, "key_id" = %s
WHERE "main_testmodel"."id" = %s'
- PARAMS = (u"'edited_test'", u'2', u'1')
# to_update = TestModel.objects.filter(id=2).update(name='updated_name', key=new_key):
QUERY = u'UPDATE "main_testmodel" SET "name" = %s, "key_id" = %s
WHERE "main_testmodel"."id" = %s'
- PARAMS = (u"'updated_name'", u'3', u'2')
Wir haben nur eine Abfrage für update()
und zwei für save()
.
Als nächstes sprechen wir über das Überschreiben save()
Methode. Es wird nur einmal offensichtlich für save()
Methode aufgerufen. Es ist erwähnenswert, dass .objects.create()
ruft auch save()
Methode.
Aber update()
ruft save()
auf Modellen nicht auf. Und wenn für update()
keine save()
Methode aufgerufen wird, werden auch die Signale nicht ausgelöst. Ausgang:
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
# TestModel.objects.get(id=1):
Manager is called [<TestModel: edited_test new_for 0>]
Manager is called [<TestModel: edited_test new_for 0>]
save() is called.
signal dispatched
signal dispatched
# to_update = TestModel.objects.filter(id=2).update(name='updated_name', key=new_key):
Manager is called [<TestModel: edited_test new_for 0>]
Wie Sie save()
löst Manager
‚s get_queryset()
zweimal sehen. Wenn update()
nur einmal.
Auflösung. Wenn Sie Ihre Werte "stumm" aktualisieren müssen, ohne save()
aufgerufen zu haben - verwenden Sie update
. Anwendungsfälle: last_seen
Benutzerfeld. Wenn Sie Ihr Modell ordnungsgemäß aktualisieren müssen, verwenden Sie save()
.
möglich Duplikat [Mit QuerySet.update() im Vergleich zu ModelInstance.save() in Django] (http://stackoverflow.com/questions/4519336/using-queryset-update-versus-modelinstance-save- in-django) – sobolevn
@Sobolevn diese Frage und Antworten sind ziemlich veraltet, seit Django war in der Version 1.0 oder 1.1 oder so ähnlich. Diese Verisons sind veraltet und werden nicht mehr unterstützt, da im Laufe der Zeit viele Änderungen vorgenommen wurden. – FallenAngel
@FallenAngel, yeah, ich habe das Datum zuerst gesehen. Aber als ich es herausgefunden habe, gab ich eine Antwort. – sobolevn