現在 を呼び出す関数がありModels.object.get()
、0 または 1 つのモデル オブジェクトを返します。except DoesNotExist
0 が返された場合は、関数の句で新しいモデル インスタンスを作成します。それ以外の場合は、新しいインスタンスを作成せずに、既存のインスタンスのフィールドを更新したいと考えています。.update()
私はもともと見つかったインスタンスを呼び出そうとしていまし.update()
たが、クエリセットでしか呼び出せないようです。.filter()
既存のインスタンスを作成または更新する必要があるかどうかを知るために長さを呼び出して比較せずに、多数のフィールドを変更するにはどうすればよいでしょうか?
8 に答える
Django 1.7 の登場により、新しいupdate_or_create
QuerySet メソッドが追加されました。これは、まさにあなたが望むことを行うはずです。データベース レベルで一意性が強制されていない場合は、潜在的な競合状態に注意してください。
ドキュメントの例:
obj, created = Person.objects.update_or_create(
first_name='John', last_name='Lennon',
defaults={'first_name': 'Bob'},
)
このメソッドは、指定されたkwargs
update_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
モデルが存在する場合にのみ更新する場合(作成せずに):
Model.objects.filter(id = 223).update(field1 = 2)
mysql クエリ:
UPDATE `model` SET `field1` = 2 WHERE `model`.`id` = 223
これがどれほど良いか悪いかはわかりませんが、次のように試すことができます。
try:
obj = Model.objects.get(id=some_id)
except Model.DoesNotExist:
obj = Model.objects.create()
obj.__dict__.update(your_fields_dict)
obj.save()
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_save
andフックを呼び出すことです。post_save
そのような場合、次のコードを使用しています。
obj, created = Model.objects.get_or_create(id=some_id)
if not created:
resp= "It was created"
else:
resp= "OK"
obj.save()
アップデート:
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')