2014-10-31 19 views
127

cosa la differenza tra l'esecuzione di due comandi:Django Modello() vs Model.objects.create()

foo = FooModel() 

e

bar = BarModel.objects.create() 

Condivide la seconda crea immediatamente un BarModel a base di dati, mentre per FooModel il metodo save() deve essere chiamato esplicitamente per aggiungerlo?

+18

Sì, è la differenza. –

risposta

113

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

per creare e salvare un oggetto in un unico passaggio, utilizzare il metodo create().

+0

I documenti del django sono un po 'contraddittori su questo punto secondo me. Ho avuto la stessa domanda e ho letto "Si noti che l'istanziazione di un modello non tocca in alcun modo il database, per questo è necessario salvare()." https://docs.djopoproject.com/en/1.10/ref/models/instances/#creating-objects – Nils

+0

Non lo vedo come contraddittorio. Generalmente in Python, si istanziano gli oggetti ponendo parentesi dopo il nome degli Oggetti non con un metodo di creazione – danidee

6

UPDATE 2017/03/15:

Ho aperto un Django-problema su questo e sembra essere preliminare accettati qui: https://code.djangoproject.com/ticket/27825

mia esperienza è che quando si utilizza il Constructor (ORM) class per riferimenti con Django 1.10.5 potrebbero esserci alcune incongruenze nei dati (cioè gli attributi dell'oggetto creato potrebbero ottenere il tipo dei dati di input invece del tipo casted della proprietà dell'oggetto ORM) Esempio :

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 
3

I due sintassi non sono equivalenti e può portare a errori imprevisti. Ecco un semplice esempio che mostra le differenze. Se si dispone di un modello:

from django.db import models 

class Test(models.Model): 

    added = models.DateTimeField(auto_now_add=True) 

E si crea un primo oggetto:

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

Quindi si tenta di creare un oggetto con la stessa chiave primaria:

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")