Django Model() vs Model.objects.create()

Какая разница между запуском двух команд:

foo = FooModel()

а также

bar = BarModel.objects.create()

Второй немедленно создает BarModel в базе данных, в то время как для FooModel метод save() должен вызываться явно, чтобы добавить его в базу данных?

Ответ 2

Два синтаксиса не эквивалентны, и это может привести к непредвиденным ошибкам. Вот простой пример, показывающий различия. Если у вас есть модель:

from django.db import models

class Test(models.Model):

    added = models.DateTimeField(auto_now_add=True)

И вы создаете первый объект:

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

Затем вы пытаетесь создать объект с тем же самым первичным ключом:

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

Ответ 3

ОБНОВЛЕНИЕ 15.3.2017:

Я открыл Django-проблему по этому вопросу, и она, кажется, предварительно принята здесь: https://code.djangoproject.com/ticket/27825

Мой опыт показывает, что при использовании класса Constructor (ORM) по ссылкам с Django 1.10.5 в данных могут быть некоторые несоответствия (т.е. Атрибуты созданного объекта могут получить тип входных данных вместо приведенного типа Свойство объекта ORM) пример:

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