web-dev-qa-db-ja.com

DjangoのModel()とModel.objects.create()の組み合わせ

2つのコマンドを実行することの違いは何ですか。

foo = FooModel()

そして

bar = BarModel.objects.create()

2番目のメソッドはすぐにデータベースにBarModelを作成しますが、FooModelの場合は、データベースに追加するためにsave()メソッドを明示的に呼び出す必要がありますか?

203
0leg

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

単一ステップでオブジェクトを作成して保存するには、create()メソッドを使用します。

189
madzohan

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")
9
Thomas Leonard

アップデート15.3.2017:

私はこれについてDjango号をオープンしました、そしてそれはここで予備的に受け入れられているようです: https://code.djangoproject.com/ticket/27825

私の経験では、Django 1.10.5を参照してConstructorORM)クラスを使用すると、データに矛盾が生じる可能性があります(つまり、作成されたオブジェクトの属性がキャストオブジェクト型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
8
Oleg Belousov