Django Model () против Model.objects.create ()

119

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

foo = FooModel()

и

bar = BarModel.objects.create()

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

  • 32
    Да, это разница.
Теги:
database

3 ответа

95
Лучший ответ

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

Чтобы создать и сохранить объект за один шаг, используйте метод create().

  • 1
    Django документы немного противоречивы по моему мнению. У меня был тот же вопрос и я прочитал: «Обратите внимание, что создание экземпляра модели никоим образом не затрагивает вашу базу данных; для этого вам нужно сохранить ()». docs.djangoproject.com/en/1.10/ref/models/instances/...
  • 4
    Я не считаю это противоречивым. Обычно в python Вы создаете экземпляры объектов, помещая квадратные скобки после имени Objects, а не методом create
Показать ещё 2 комментария
5

ОБНОВЛЕНИЕ 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
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")

Ещё вопросы

Сообщество Overcoder
Наверх
Меню