Django Model()とModel.objects.create()


267

2つのコマンドの実行の違い:

foo = FooModel()

そして

bar = BarModel.objects.create()

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


47
はい、それが違いです。
Daniel Roseman、2014年

回答:


247

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

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


3
私の意見では、django docsはこの点で少し矛盾しています。同じ質問があり、「モデルのインスタンス化はデータベースに一切影響を与えないことに注意してください。そのためには、save()を実行する必要があります。」docs.djangoproject.com/en/1.10/ref/models/instances/...
ニルス

6
それは矛盾しているとは思わない。一般にpythonでは、createメソッドではなく、オブジェクト名の後に角かっこを付けてオブジェクトをインスタンス化します
danidee

3
@danidee私はそれが矛盾しないことに同意しますが、それは確かに誤解を招くものです。主にNilsのリンクでは、example1は「インスタンス化」されていますが、example2は「インスタンス化+保存」です。また、モデルを保存する方法を知りたいときに、「クエリ」ドキュメントを参照する必要があるのはなぜですか。django docには本当に多くの苦労があります。
中村

3
@中村INSERTはクエリだから?
Juanjo Conti

16

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

したがって.create()、必須フィールド(null=False)が欠落している場合でもオブジェクトを作成しますか?プロジェクトにテストを追加していて、create予期しない結果が発生しています
Vaibhav Vishal

いいえ、それはすべきではありません... Djangoでは、一部のフィールドタイプが少し奇妙に機能します。たとえば、提供CharFieldされnull=Falseない場合に設定されてもエラーは発生しません。これは、Djangoがデフォルトで文字列を空の文字列に設定するため、""技術的にはそうではないためですnull
Thomas Leonard

ええ、私はcharフィールドとフィールドフィールド(基本的にcharフィールドも)でのみ問題を抱えています。を使用してobj = MyModel()obj.full_clean()今のところ。
Vaibhav Vishal

10

アップデート15.3.2017:

私はこれについてDjangoの問題を公開しましたが、ここで予備的に受け入れられているようです:https : //code.djangoproject.com/ticket/27825

私の経験では、Djangoを参照してConstructorORM)クラスを使用する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

Josh Smeatonは、型をキャストする開発者自身の責任に関して優れた答えを出しました。回答を更新してください。
Artur Barseghyan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.