Django Model () ve Model.objects.create () karşılaştırması


267

İki komutu çalıştırmak arasındaki fark nedir:

foo = FooModel()

ve

bar = BarModel.objects.create()

İkincisi BarModelveritabanında hemen bir a oluşturur mu FooModel, bunun için ise save()metodun veritabanına eklenmesi için açıkça çağrılması gerekir mi?


47
Evet, fark bu.
Daniel Roseman

Yanıtlar:


247

https://docs.djangoproject.com/en/stable/topics/db/queries/#creating-objects

Tek bir adımda bir nesne oluşturmak ve kaydetmek için create()yöntemi kullanın .


3
Django belgeleri bence bu noktada biraz çelişkili. Aynı soruyu sordum ve "Bir modeli örneklemenin veritabanınıza hiçbir şekilde dokunmadığını unutmayın; bunun için kaydetmeniz gerekir ()." docs.djangoproject.com/tr/1.10/ref/models/instances/…
Nils

6
Bunu çelişkili görmüyorum. Genellikle
python'da

3
@danidee Bunun çelişkili olmadığını kabul ediyorum, ama kesinlikle yanıltıcı. Temel olarak Nils'in bağlantısında, example1 "somutlaştırır", ancak example2 "somutlaştırır + kurtarır" dır. Ayrıca, bir modeli nasıl kaydedeceğimizi bilmek istediğimde neden "sorgular" belgesine başvurmalıyım? Django doktorunda gerçekten çok acı var.
Nakamura

3
@Nakamura çünkü INSERT bir sorgu?
Juanjo Conti

16

İki sözdizimi eşdeğer değildir ve beklenmedik hatalara yol açabilir. Farklılıkları gösteren basit bir örnek. Bir modeliniz varsa:

from django.db import models

class Test(models.Model):

    added = models.DateTimeField(auto_now_add=True)

Ve bir ilk nesne oluşturursunuz:

foo = Test.objects.create(pk=1)

Sonra aynı birincil anahtarla bir nesne oluşturmaya çalışın:

foo_duplicate = Test.objects.create(pk=1)
# returns the error:
# django.db.utils.IntegrityError: (1062, "Duplicate entry '1' for key 'PRIMARY'")

foo_duplicate = Test(pk=1).save()
# returns the error:
# django.db.utils.IntegrityError: (1048, "Column 'added' cannot be null")

böylece .create()bir zorunlu alan (hatta eğer bir nesne oluşturur null=False) eksik? Projeme testler ekliyorum ve createbeklenmedik sonuçlar elde
Vaibhav Vishal

Hayır, olmamalı ... Bazı alan türleri Django'da biraz garip davranmasına rağmen. Örneğin, belirtilmemişse bir hata vermeyecek CharFieldolsa bile null=False: bunun nedeni, Django'nun dizeleri varsayılan olarak boş bir dizeye ayarlamasıdır, ""bu nedenle teknik olarak değilnull
Thomas Leonard

evet, sadece char alanları ve alan alanı ile ilgili sorunlar yaşıyorum (temelde char alan da). Kullanılması obj = MyModel()sonra, obj.full_clean()şimdilik.
Vaibhav Vishal

10

15.3.2017 GÜNCELLEME:

Bu konuda bir Django sorunu açtım ve burada ön kabul gibi görünüyor: https://code.djangoproject.com/ticket/27825

Benim tecrübem, Constructor( ORM) sınıfını Django ile yapılan başvurularda kullanırken 1.10.5verilerde bazı tutarsızlıklar olabilir (yani, oluşturulan nesnenin öznitelikleri ORM nesnesi özelliğinin döküm türü yerine girdi verilerinin türünü alabilir) :

models

class Payment(models.Model):
     amount_cash = models.DecimalField()

some_test.py - object.create

Class SomeTestCase:
    def generate_orm_obj(self, _constructor, base_data=None, modifiers=None):
        objs = []
        if not base_data:
            base_data = {'amount_case': 123.00}
        for modifier in modifiers:
            actual_data = deepcopy(base_data)
            actual_data.update(modifier)
            # Hacky fix,
            _obj = _constructor.objects.create(**actual_data)
            print(type(_obj.amount_cash)) # Decimal
            assert created
           objs.append(_obj)
        return objs

some_test.py - Constructor()

Class SomeTestCase:
    def generate_orm_obj(self, _constructor, base_data=None, modifiers=None):
        objs = []
        if not base_data:
            base_data = {'amount_case': 123.00}
        for modifier in modifiers:
            actual_data = deepcopy(base_data)
            actual_data.update(modifier)
            # Hacky fix,
            _obj = _constructor(**actual_data)
            print(type(_obj.amount_cash)) # Float
            assert created
           objs.append(_obj)
        return objs

Josh Smeaton, döküm türlerine geliştiricinin kendi sorumluluğu konusunda mükemmel bir cevap verdi . Lütfen cevabınızı güncelleyin.
Artur Barseghyan
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.