Django modeli oluşturun veya varsa güncelleyin


115

Kişi kimliği yoksa, Kişi gibi bir model nesne oluşturmak istiyorum, yoksa o kişinin nesnesini alacağım.

Aşağıdaki gibi yeni bir kişi oluşturma kodu:

class Person(models.Model):
    identifier = models.CharField(max_length = 10)
    name = models.CharField(max_length = 20)
    objects = PersonManager()

class PersonManager(models.Manager):
    def create_person(self, identifier):
        person = self.create(identifier = identifier)
        return person

Ancak mevcut kişi nesnesini nereden kontrol edeceğimi ve alacağımı bilmiyorum.

Yanıtlar:


169

"Varsa güncelle başka oluştur" kullanım senaryosunu arıyorsanız , lütfen @Zags mükemmel yanıtına bakın


Django zaten vardır get_or_create, https://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create

Senin için şunlar olabilir:

id = 'some identifier'
person, created = Person.objects.get_or_create(identifier=id)

if created:
   # means you have created a new person
else:
   # person just refers to the existing one

Django 1.9 kullanıyorum ve bana şunu veriyor: AttributeError: 'QuerySet' nesnesinin 'update_or_create' niteliği yok
Ofek Gila

1
Garip @OfekGila, hem kaynak kodu ve dokümantasyon onayla QuerySetvardırupdate_or_create
bakkal

2
Benim durumumda, tanımlayıcı yerine, bir arada benzersiz oluşturan alanlar grubum var. Bu davanın kullanımı nasıl?
Rakmo

192

Sorunuzun get_or_create yöntemini mi (en azından Django 1.3'te mevcuttur) yoksa update_or_create yöntemini mi (Django 1.7'de yeni ) sorup sormadığı belli değil . Kullanıcı nesnesini nasıl güncellemek istediğinize bağlıdır.

Örnek kullanım aşağıdaki gibidir:

# In both cases, the call will get a person object with matching
# identifier or create one if none exists; if a person is created,
# it will be created with name equal to the value in `name`.

# In this case, if the Person already exists, its existing name is preserved
person, created = Person.objects.get_or_create(
        identifier=identifier, defaults={"name": name}
)

# In this case, if the Person already exists, its name is updated
person, created = Person.objects.update_or_create(
        identifier=identifier, defaults={"name": name}
)

12
+1 update_or_createçünkü bu kullanım durumu için nesneyi tekrar get_or_createçağırmaktan daha iyidir save().
bakkal

Benim durumumda, tanımlayıcı yerine, bir arada benzersiz oluşturan alanlar grubum var. Bu davanın kullanımı nasıl?
Rakmo

1
@OmkarDeshpande tanımlayıcısı yalnızca bir örnektir; geçerli herhangi bir django sorgusunu iletebilirsiniz, örneğinPerson.objects.get_or_create(a=a, b=b, c=c, defaults={"name": name})
Zags

Oluşturulan Kişiye varsayılanlardan daha fazla alan eklemek istersem ne olur?
Lo Bellin

@LoBellin, defaultsbu işlevlerin argümanında, modele hangi alanların eklenmesini istediğinizi belirtirsiniz. Modelinizin alanlarında belirtilen varsayılanlarla hiçbir ilgisi yoktur
Zags

10

Django'nun bunun için desteği var, get_or_create'i kontrol edin

person, created = Person.objects.get_or_create(name='abc')
if created:
    # A new person object created
else:
    # person object already exists

4

Update_or_create yalnızca küçük miktarda nesne için iyi çalışır, ancak büyük bir koleksiyon üzerinde çalışıyorsanız, iyi ölçeklenmez. update_or_create her zaman önce bir SELECT ve ardından bir UPDATE çalıştırır.

for the_bar in bars:
    updated_rows = SomeModel.objects.filter(bar=the_bar).update(foo=100)
        if not updated_rows:
            # if not exists, create new
            SomeModel.objects.create(bar=the_bar, foo=100)

Bu en iyi ihtimalle yalnızca ilk güncelleme sorgusunu çalıştırır ve yalnızca sıfır satırla eşleşirse başka bir INSERT sorgusu çalıştırır. Satırların çoğunun gerçekten mevcut olmasını bekliyorsanız bu, performansınızı büyük ölçüde artıracaktır.

Yine de her şey kullanım durumunuza bağlı. Çoğunlukla eklemeler bekliyorsanız, o zaman belki de bulk_create () komutu bir seçenek olabilir.


3

Soru başlığınız, soru gövdesinde açıklandığı gibi alma veya oluşturma yerine nasıl oluşturulacağını veya güncelleneceğini soruyor gibi göründüğü için bir cevap eklemeyi düşündüm.

Bir nesneyi oluşturmak veya güncellemek istediyseniz, .save () yöntemi , dokümanlarda varsayılan olarak bu davranışa zaten sahiptir :

Django, INSERT veya UPDATE SQL deyimlerini kullanma ihtiyacını özetler. Özellikle, save () 'i çağırdığınızda, Django şu algoritmayı izler:

Nesnenin birincil anahtar niteliği, True olarak değerlendirilen bir değere ayarlanmışsa (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 çalıştırır.

'GÜNCELLEME herhangi bir şey güncellemediyse' dedikleri zaman, aslında nesneye verdiğiniz kimliğin veritabanında mevcut olmadığı duruma atıfta bulunduklarını belirtmek gerekir.


1

Oluşturduğunuzdaki girdilerden biri birincil anahtar ise, bu yeterli olacaktır:

Person.objects.get_or_create(id=1)

Aynı birincil anahtara sahip iki veriye izin verilmediğinden, varsa otomatik olarak güncellenecektir.

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.