tek bir sorgu kümesiyle veritabanı kaydını seçin ve güncelleyin


140

Bir updateand selectifadesini querysetiki sorgu yapmak yerine nasıl aynı anda çalıştırırım : - biri nesneyi seçmek için - ve diğeri nesneyi güncellemek için

SQL'deki eşdeğeri şöyle bir şey olacaktır:

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

Yanıtlar:


269

Sorgu kümesi nesne updateyöntemini kullanın :

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

96
Sadece makul bir uyarı ... eğer böyle bir updateyöntemi kullanırsanız, o modele veya diğer "kod maddelerine" eklenen herhangi bir sinyal nesnelere karşı çalışmayacaktır. Yanmış birinden sadece bir işaret :)
DMac the Destroyer

@DMactheDestroyer ahbap bu değerli bilgi için teşekkürler. Öyleyse, eski güncelleme yöntemini kullanmalı mıyız? (yani) al ve kaydet?

@ iyi öğrenmek dostum, hepsi senaryonuza bağlı. updateYöntem kütle güncellemeleri için harika ama bu size ateş el ile de olması gerekir diye nesneye bağlı herhangi sinyalleri incelememiz gerekmektedir kullanmak kafanın içinde bir uyarı yola gerektiğini
DMAc Destroyer

3
Güncelleme işlevinde mevcut model örneğine erişmek mümkün mü? beğenMyModel.objects.filter(pk=some_value).update(field1=self.data)
Dipak

8
@DipakChandranP Altı yaşındaki bir çocuğa yorum yapmak yerine yeni bir soru sormalısınız. Ancak F () ifadeleri muhtemelen istediğinizi istiyor.
Daniel Roseman

70

Django veritabanı nesneleri, nesneleri oluşturmak ve değiştirmek için aynı save () yöntemini kullanır.

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

Django, GÜNCELLEME ve INSERT'i nasıl bilir
Nesnenin birincil anahtar niteliği True olarak değerlendirilen bir değere ayarlanırsa (yani, Yok veya boş dizeden farklı bir değer), Django bir GÜNCELLEME yürütür. Nesnenin birincil anahtar niteliği ayarlanmamışsa veya GÜNCELLEME hiçbir şeyi güncellemediyse, Django bir INSERT yürütür.

Referans: https://docs.djangoproject.com/en/1.9/ref/models/instances/


17

Bu cevap, yukarıdaki iki yaklaşımı karşılaştırır. Çok sayıda nesneyi tek bir satırda güncellemek istiyorsanız, şunu gidin:

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

Aksi takdirde, sorgu kümesini yinelemeniz ve tek tek nesneleri güncellemeniz gerekir:

#Approach 2    
objects = MyModel.objects.filter(field1='Computer')
for obj in objects:
    obj.field2 = 'cool'
    obj.save()
  1. Yaklaşım 1 daha hızlıdır çünkü, 'n + 1' veritabanı sorguları yapan yaklaşım 2'ye kıyasla yalnızca bir veritabanı sorgusu yapar. (Sorgu kümesindeki n öğe için)

  2. İlk yaklaşım bir db sorgusu yapar, yani UPDATE, ikincisi iki tane yapar: SELECT ve ardından UPDATE.

  3. Takas, güncelleme updated_onveya benzeri ilgili alanlar gibi herhangi bir tetikleyiciniz olduğunu varsayalım , doğrudan güncellemede, yani yaklaşım 1'de tetiklenmeyecek.

  4. Yaklaşım 1, bir sorgu kümesinde kullanılır, bu nedenle, yaklaşım 2 durumunda değil, aynı anda birden çok nesneyi güncellemek mümkündür.


1 ile ilgili olarak - Sorgu sonucunun ilk sorgu çağrısında önbelleğe alınacağını düşünüyorum, bu nedenle aslında DB'ye yalnızca bir çağrı var.
user2340939

2

sadece bir durumda serializer, çok basit bir şekilde güncelleme yapabilirsiniz!

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

    my_model_serializer.save()

sadece bir formşeylerde bir durumda !

instance = get_object_or_404(MyModel, id=id)
form = MyForm(request.POST or None, instance=instance)
if form.is_valid():
    form.save()

Serileştiricilerin Djanog Rest Framework'ten olduğunu ve Django'nun uygun olmadığını düşünüyorum.
Code-Apprentice

1
Evet, ancak Django formDjango Proper'dan.
Jamil Noyda
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.