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.