93

現在 を呼び出す関数がありModels.object.get()、0 または 1 つのモデル オブジェクトを返します。except DoesNotExist0 が返された場合は、関数の句で新しいモデル インスタンスを作成します。それ以外の場合は、新しいインスタンスを作成せずに、既存のインスタンスのフィールドを更新したいと考えています。.update()私はもともと見つかったインスタンスを呼び出そうとしていまし.update()たが、クエリセットでしか呼び出せないようです。.filter()既存のインスタンスを作成または更新する必要があるかどうかを知るために長さを呼び出して比較せずに、多数のフィールドを変更するにはどうすればよいでしょうか?

4

8 に答える 8

106

Django 1.7 の登場により、新しいupdate_or_createQuerySet メソッドが追加されました。これは、まさにあなたが望むことを行うはずです。データベース レベルで一意性が強制されていない場合は、潜在的な競合状態に注意してください。

ドキュメントの例:

obj, created = Person.objects.update_or_create(
    first_name='John', last_name='Lennon',
    defaults={'first_name': 'Bob'},
)

このメソッドは、指定されたkwargsupdate_or_createに基づいてデータベースからオブジェクトを取得しようとします。一致が見つかった場合は、ディクショナリに渡されたフィールドを更新します。defaults


Django 1.7 より前:

必要に応じてモデル フィールドの値を変更し、呼び出し.save()て変更を永続化します。

try:
    obj = Model.objects.get(field=value)
    obj.field = new_value
    obj.save()
except Model.DoesNotExist:
    obj = Model.objects.create(field=new_value)
# do something else with obj if need be
于 2012-09-12T05:38:55.887 に答える
53

モデルが存在する場合にのみ更新する場合(作成せずに):

Model.objects.filter(id = 223).update(field1 = 2)

mysql クエリ:

UPDATE `model` SET `field1` = 2 WHERE `model`.`id` = 223
于 2015-05-20T15:15:56.940 に答える
25

これがどれほど良いか悪いかはわかりませんが、次のように試すことができます。

try:
    obj = Model.objects.get(id=some_id)
except Model.DoesNotExist:
    obj = Model.objects.create()
obj.__dict__.update(your_fields_dict) 
obj.save()
于 2012-09-12T05:49:22.350 に答える
10

updateこれは、各インスタンスにメソッドを与える任意のモデル クラスにミックスできる mixin です。

class UpdateMixin(object):
    def update(self, **kwargs):
        if self._state.adding:
            raise self.DoesNotExist
        for field, value in kwargs.items():
            setattr(self, field, value)
        self.save(update_fields=kwargs.keys())

このself._state.addingチェックでは、モデルがデータベースに保存されているかどうかがチェックされ、保存されていない場合はエラーが発生します。

(注: このupdate方法は、モデルを更新する必要があり、インスタンスが既にデータベースに保存されていることがわかっている場合に、元の質問に直接回答するためのものですupdate_or_create。Platinum Azure の回答で紹介されている組み込みの方法は、他のユース ケースを既にカバーしています。 )

次のように使用します (これをユーザー モデルに混合した後)。

user = request.user
user.update(favorite_food="ramen")

このアプローチのもう 1 つの利点は、より優れた API を使用できることに加えて、別のプロセスが同じモデルを更新している場合にアトミック性の問題を回避しながら、 pre_saveandフックを呼び出すことです。post_save

于 2016-10-16T22:58:54.067 に答える
0

そのような場合、次のコードを使用しています。

obj, created = Model.objects.get_or_create(id=some_id)

if not created:
   resp= "It was created"
else:
   resp= "OK"
   obj.save()
于 2012-09-12T07:28:17.333 に答える
0

アップデート:

1 -個々のインスタンス : インスタンスを取得して手動で更新する get() 個々のオブジェクトを取得する

post = Post.objects.get(id=1)
post.title = "update title"
post.save()

2 -インスタンスのセット: filter() メソッドによって返されるクエリセットでのみ機能する update() メソッドを使用します。

Post.objects.filter(author='ahmed').update(title='updated title for ahmed')
于 2021-11-15T12:14:32.520 に答える